UDP通信
- UDP是无链接的,先启动哪一端都不会报错
- UDP协议是数据报协议,发空的时候也会自带报头,因此客户端输入空,服务端也能收到
- UDP协议一般不用于传输大数据。
- UDP套接字虽然没有粘包问题,但是不能替代TCP套接字,因为UDP协议有一个缺陷:如果数据发送的途中,数据丢失,则数据就丢失了,而TCP协议则不会有这种缺陷,因此一般UDP套接字用无关紧要的数据发送,例如QQ聊天。
# server.py
import socket
soc = socket.socket(type=socket.SOCK_DGRAM)
soc.bind(('127.0.0.1', 8008))
while True:
data, addr = soc.recvfrom(1024)
print(data)
soc.sendto(data.upper(), addr)
# client.py
import socket
soc = socket,socket(type=socket.SOCK_DGRAM)
while True:
msg = input('>>>:')
soc.sendto(msg, ('127.0.0.1', 8008))
data = soc.recvfrom(1024)[0]
基于socketserver实现并发的socket变成
基于tcp的套接字,关键就是两个循环,一个链接循环,一个通信循环
socketserver模块中分两大类:server类(解决链接问题)和request类(解决通信问题)
1、TCP
# server.py
import socketserver
class MyHandler(socketserver.BaseRequestHandler):
def handle(self):
# 通信循环
while True:
# print(self.client_address)
# print(self.request) #self.request=conn
try:
data = self.request.recv(1024)
if len(data) == 0: break
self.request.send(data.upper())
except ConnectionResetError:
break
if __name__ == '__main__':
# 实例化得到一个tcp连接的对象,Threading意思是说,只要来了请求,它自动的开线程来处理连接跟交互数据
# 第一个参数是绑定的地址,第二个参数传一个类
server = socketserver.ThreadingTCPServer(('127.0.0.1', 8082), MyTcp)
# 一直在监听
# 这么理解:只要来一个请求,就起一个线程(造一个人,做交互)
server.serve_forever()
2、UDP
# server.py
import socketserver
class MyHandler(socketserver.BaseRequestHandler):
def handle(self):
# 通信循环
print(self.client_address)
print(self.request)
data = self.request[0]
print('客户消息', data)
self.request[1].sendto(data.upper(), self.client_address)
if __name__ == '__main__':
s = socketserver.ThreadingUDPServer(('127.0.0.1', 8080), MyHandler)
s.serve_forever()