***Python之UDP***
UDP(user datagram protocol,用户数据报协议)是无连接的,面向消息的,提供高效率服务。不会使用块的合并优化算法,, 由于UDP支持的是一对多的模式,所以接收端的skbuff(套接字缓冲区)采用了链式结构来记录每一个到达的UDP包,在每个UDP包中就有了消息头(消息来源地址,端口等信息),这样,对于接收端来说,就容易进行区分处理了。
即面向消息的通信是有消息保护边界的。
UDP不粘包。
Server:
1 #服务端第一个特点是: 2 # 一直运行提供服务(链接循环),(基于一个链接通信循环) 3 # 绑定一个唯一的地址 4 # 5 # import socket 6 # phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机 7 # phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加 8 # phone.bind(('127.0.0.1',8080)) #绑定手机卡 9 # 10 # phone.listen(5) #开机 ?5 11 # 12 # print('starting....') 13 # while True: #链接循环 14 # conn,addr=phone.accept() #等待电话链接 15 # 16 # print('电话线路是',conn) 17 # print('客户端的手机号是',addr) 18 # 19 # while True: #通信循环 20 # try: #应对windows系统 21 # data=conn.recv(1024) #收消息 ?1024 22 # if not data:break #linux系统 23 # print('客户端发来的消息是',data) 24 # 25 # conn.send(data.upper()) 26 # except Exception: 27 # break 28 # 29 # conn.close() 30 # 31 # phone.close() 32 33 34 import socketserver 35 36 #Ftpserver(conn, client_addr, obj) 37 38 class FTPserver(socketserver.BaseRequestHandler): #通讯 BaseRequestHandler是必须有的。 39 #handle方法是必须要有的。 40 def handle(self): 41 print('=-=====>',self.request) 42 print(self.request) #套接字对象,好似拿到con 43 while True: 44 data=self.request.recv(1024) 45 print(data) 46 self.request.send(data.upper()) #发送数据 47 48 49 if __name__ == '__main__': 50 obj=socketserver.ThreadingTCPServer(('127.0.0.1',8080),FTPserver) 51 #线程,针对每个客户端的请求独立去做事 52 print(obj.server_address) 53 print(obj.RequestHandlerClass) 54 print(obj.socket) 55 56 obj.serve_forever() #链接循环,永远提供服务。
Client:
1 import socket 2 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 3 phone.connect(('127.0.0.1',8080)) 4 5 while True: #通信循环 6 msg=input('>>: ').strip() 7 if not msg:continue 8 phone.send(msg.encode('utf-8')) 9 # print('has send===========>') 10 data=phone.recv(1024) 11 # print('has recv===========>') 12 print(data) 13 14 phone.close()
基于UDP的套接字聊天:
Server端:
1 import socket 2 3 4 udpserver=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) 5 udpserver.bind(('127.0.0.1',8080)) 6 7 while True: #通讯循环 8 data,client_addr=udpserver.recvfrom(1024) 9 print('======>',data.decode('utf-8')) 10 print(client_addr) 11 # msg=input('>>: ') 12 udpserver.sendto(data.upper(),client_addr)
Client端:
1 import socket 2 3 udpclient=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) 4 5 server_ip_port=('127.0.0.1',8080) 6 while True: 7 inp=input(">>: ") 8 udpclient.sendto(inp.encode('utf-8'),server_ip_port) 9 10 data,server_addr=udpclient.recvfrom(1024) 11 print(data.decode('utf-8'))
UDP协议发包测试:
在win的上边会报错,机制问题,在Linux中就OK。
Server端:
1 import socket 2 3 4 udpserver=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) 5 udpserver.bind(('127.0.0.1',8080)) 6 7 data,client_addr=udpserver.recvfrom(2) 8 print('======>',data.decode('utf-8')) 9 10 11 12 data,client_addr=udpserver.recvfrom(2) 13 print('======>',data.decode('utf-8'))
Client端:
1 import socket 2 3 udpclient=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) 4 5 server_ip_port=('192.168.16.114',8080) 6 7 8 udpclient.sendto('hello'.encode('utf-8'),server_ip_port) 9 udpclient.sendto('shibushiloule'.encode('utf-8'),server_ip_port)
UDP的SocketServer: 实现并发
Server端:
1 import socketserver 2 3 class FtpServer(socketserver.BaseRequestHandler): 4 def handle(self): 5 print(self.request[0]) 6 print(self.request[1]) 7 self.request[1].sendto('嘎嘎嘎'.encode('utf-8'),self.client_address) 8 9 if __name__ == '__main__': 10 obj=socketserver.ThreadingUDPServer(('127.0.0.1',8080),FtpServer) 11 obj.serve_forever()
Client端:
1 import socket 2 3 udpclient=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) 4 5 server_ip_port=('127.0.0.1',8080) 6 while True: 7 inp=input(">>: ") 8 udpclient.sendto(inp.encode('utf-8'),server_ip_port) 9 10 data,server_addr=udpclient.recvfrom(1024) 11 print(data.decode('utf-8'))