0
点赞
收藏
分享

微信扫一扫

Python从门到精通(七):网络-04-创建TPC和UDP服务接口

本章了解下socket编程以及tpc和udp,TCP/IP 中有两个具有代表性的传输层协议分别是 TCP 和 UDP,它们的主要区别是:1、udp是无连接的(广播),tcp是面向连接的;2、udp是不可靠传输,tcp是可靠传输;3、udp是面向报文传输,tcp是面向字节流传输。

其它的TCP,​​UDP​​,IP,FTP,HTTP,ICMP,SMTP 等也都属于 TCP/IP 族内的协议。

一、TCP

1.1、Server

from socketserver import BaseRequestHandler, TCPServer

class EchoHandler(BaseRequestHandler):
def handle(self):
print(f'Got connection from {self.client_address}')
while True:
# msg = self.request.recv(8192)
if not (msg := self.request.recv(8192)):
break
self.request.send(msg)
print(f'received msg: {msg}')

if __name__ == '__main__':
serv = TCPServer(('', 20000), EchoHandler)
serv.serve_forever()

1.2、Client

from socket import socket, AF_INET, SOCK_STREAM

s = socket(AF_INET, SOCK_STREAM)
s.connect(('localhost', 20000))
s.send(b'Hello, world!')

s.recv(8192)

1.3、SuperServer

from socketserver import StreamRequestHandler, TCPServer
from socketserver import ThreadingTCPServer

class EchoHandler(StreamRequestHandler):
def handle(self):
print(f'Got connection from {self.client_address}')
# self.rfile is a file-like object for reading
for line in self.rfile:
# self.wfile is a file-like object for writing
self.wfile.write(line)
#单线程
if __name__ == '__main__':
serv = TCPServer(('', 20000), EchoHandler)
serv.serve_forever()

#多线程
if __name__ == '__main__':
serv = ThreadingTCPServer(('', 20000), EchoHandler)
serv.serve_forever()

#线程池
if __name__ == '__main__':
from threading import Thread
NWORKERS = 16
serv = TCPServer(('', 20000), EchoHandler)
for n in range(NWORKERS):
t = Thread(target=serv.serve_forever)
t.daemon = True
t.start()
serv.serve_forever()

#bind_and_activate=False 允许改变一些基础配置
import socket
if __name__ == '__main__':
serv = TCPServer(('', 20000), EchoHandler, bind_and_activate=False)
# Set up various socket options
serv.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# Bind and activate
serv.server_bind()
serv.server_activate()
serv.serve_forever()


if __name__ == '__main__':
TCPServer.allow_reuse_address = True
serv = TCPServer(('', 20000), EchoHandler)
serv.serve_forever()

1.4、Socket

import socket
from socketserver import StreamRequestHandler

class EchoHandler(StreamRequestHandler):
# Optional settings (defaults shown)
# Timeout on all socket operations
timeout = 5
# Read buffer size
rbufsize = -1
# Write buffer size
wbufsize = 0
# Sets TCP_NODELAY socket option
disable_nagle_algorithm = False

def handle(self):
print(f'Got connection from {self.client_address}')
try:
for line in self.rfile:
# self.wfile is a file-like object for writing
self.wfile.write(line)
except socket.timeout:
print('Timed out!')
from socket import socket, AF_INET, SOCK_STREAM

def echo_handler(address, client_sock):
print(f'Got connection from {address}')
while True:
# msg = client_sock.recv(8192)
if not (msg := client_sock.recv(8192)):
break
client_sock.sendall(msg)
client_sock.close()

def echo_server(address, backlog=5):
sock = socket(AF_INET, SOCK_STREAM)
sock.bind(address)
sock.listen(backlog)
while True:
client_sock, client_addr = sock.accept()
echo_handler(client_addr, client_sock)

if __name__ == '__main__':
echo_server(('', 20000))

二、UDP

1.1、Server

from socketserver import BaseRequestHandler, UDPServer
import time

class TimeHandler(BaseRequestHandler):
def handle(self):
print(f'Got connection from {self.client_address}')
# Get message and client socket
msg, sock = self.request
resp = time.ctime()
sock.sendto(resp.encode('ascii'), self.client_address)
#单线程
if __name__ == '__main__':
serv = UDPServer(('', 20000), TimeHandler)
serv.serve_forever()
#多线程
from socketserver import ThreadingUDPServer
if __name__ == '__main__':
serv = ThreadingUDPServer(('',20000), TimeHandler)
serv.serve_forever()

1.2、Client

from socket import socket, AF_INET, SOCK_DGRAM

s = socket(AF_INET, SOCK_DGRAM)
s.sendto(b'', ('localhost', 20000))

s.recvfrom(8192)

1.3、Socket

from socket import socket, AF_INET, SOCK_DGRAM
import time

def time_server(address):
sock = socket(AF_INET, SOCK_DGRAM)
sock.bind(address)
while True:
msg, addr = sock.recvfrom(8192)
print(f'Got message from {addr}')
resp = time.ctime()
sock.sendto(resp.encode('ascii'), addr)

if __name__ == '__main__':
time_server(('', 20000))
举报

相关推荐

0 条评论