***Python之UDP***

***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() #链接循环,永远提供服务。
View Code

  

    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()
View Code

    基于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)
View Code

  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'))
View Code

  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'))
View Code

    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)
View Code

  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()
View Code

     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'))
View Code

链接

原文地址:https://www.cnblogs.com/george92/p/9349663.html