UDP
UDP
特点:
-
udp 不会管客户端或者服务端是否收到,它只管发,所以不可靠.
-
可以发空(数据报协议,自带头)
-
客户端和服务端可以又一方没在线(因为不需要建立连接)
-
并且由于不需要建立连接所以会发生丢包,导致数据不全。
一,简单的udp
1.1简单的udp
-
server端
import socket server = socket.socket(type=socket.SOCK_DGRAM) server.bind(('127.0.0.1',8008)) #udp是不需要建立连接的,可以直接发送 #udp不需要进行监听 #剩下的部分和tcp是一样的 data,addr= server.recvfrom(1024) #data 是指传送过来的数据的部分,第二个参数addr是客户地址 print(data,addr) #发送数据的时候,一定要加上地址 server.sendto(data.upper(),addr)
-
client端
import socket client = socket.socket(type=socket.SOCK_DGRAM) #直接发送就行 client.sendto(b'chen',('127.0.0.1',8008)) data,addr = client.recvfrom(1024) print(data,addr)
1.2 简单通信循环
- server
import socket
server = socket.socket(type=socket.SOCK_DGRAM)
server.bind(('127.0.0.1',8008))
while True:
data,addr = server.recvfrom(1024)
print(data)
server.sendto(data.upper(),addr)
2.client
import socket
client = socket.socket(type=socket.SOCK_DGRAM)
while True:
msg = input('>>:')
client.sendto(msg.encode('utf-8'),('127.0.0.1',8008))
data = client.recvfrom(1024)
print(data)
二、udp是否粘包
udp协议没有粘包问题(udp协议又叫数据报协议),可以发空,tcp不行
-
server
#udp协议没有粘包问题(udp协议又叫数据报协议),可以发空,tcp不行 import socket server = socket.socket(type=socket.SOCK_DGRAM) server.bind(('127.0.0.1',8003)) # while True: # data,addr = server.recvfrom(1024) # print(data) # server.sendto(data.upper(),addr) data,addr = server.recvfrom(1024) print(data) data,addr = server.recvfrom(1024) print(data) data,addr = server.recvfrom(1024) print(data) data,addr = server.recvfrom(1024) print(data)
-
client
import socket client = socket.socket(type=socket.SOCK_DGRAM) client.sendto('chen'.encode('utf8'),('127.0.0.1',8003)) client.sendto('hello'.encode('utf8'),('127.0.0.1',8003)) client.sendto('world'.encode('utf8'),('127.0.0.1',8003)) client.sendto(''.encode('utf8'),('127.0.0.1',8003))
三、socketserver多线程通信
支持多线程,在udp中又多线程的情况下会结束上一个线程
-
server
#使用socketserver写服务端 #导入模块 import socketserver #自己定义一个类,必须继承BaseRequestHandler class MyTcp(socketserver.BaseRequestHandler): #必须重写handle方法 def handle(self): print(self) #数据 print(self.request[0]) print(self.request[1]) print(type(self.request[1])) self.request[1].sendto('xxxx'.encode('utf-8'),self.client_address) if __name__ == '__main__': #实例化得到一个tcp连接的对象,Threading意思是说,只要来了请求, # 它自动的开线程来处理连接跟交互数据 #第一个参数是绑定的地址,第二个参数传一个类 server=socketserver.ThreadingUDPServer(('127.0.0.1',8008),MyTcp) #一直在监听 server.serve_forever()
-
client1
import socket client = socket.socket(type=socket.SOCK_DGRAM) client.sendto('chen'.encode('utf8'),('127.0.0.1',8009)) data = client.recvfrom(1024) print(data)
-
client2
import socket client = socket.socket(type=socket.SOCK_DGRAM) client.sendto('chen'.encode('utf8'),('127.0.0.1',8009)) data = client.recvfrom(1024) print(data)