udp及socketserver模块
基于udp的socket
我们上一节讲了基于tcp的socket,他的第一步是先获取一个socket对象,然后绑定ip和端口号,然后监听,接下来建立通信通道。然后就可以进行发送接收数据的操作了。
而基于udp的socket不一样,我们知道,udp协议它是一种不可靠的,速度高的协议,他和tcp协议的协议的区别是,tcp发送接收数据一定需要建立通道,而udp不需要,tcp发送数据对方接受到之后会有回执,而udp不会有。
udp_server
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 数据报协议-》UDP
server.bind(('127.0.0.1', 8080))
while True:
data, client_addr = server.recvfrom(1024)
print('===>', data, client_addr)
server.sendto(data.upper(), client_addr)
server.close()
udp_client
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 数据报协议-》UDP
while True:
msg = input('>>: ').strip() # msg=''
client.sendto(msg.encode('utf-8'), ('127.0.0.1', 8080))
data, server_addr = client.recvfrom(1024)
print(data)
client.close()
因此,和tcp不同,udp可以随便向对方的发送数据,而不用管对方是否有收到,因此有可能就会发生丢包的现象。
udp协议的特点
-可以发空(数据报协议,有头)
-不需要建连接
-不会粘包
-不可靠(客户端,服务端谁断开都不受影响)
socketserver的使用(并发)
在我们还没有学习并发编程之前,有这么一个模块,他可以来实现开启多线程的功能。
具体用法如下
server端(tcp)
class MyTcp(socket.BaseRequestHandler):
def handle(self):
#你的传送接收数据的代码以及其他业务逻辑
self.request.recv(1024)
self.request.send(b'xxxx',)
server=socketserver.ThreadingTcpServer(('127.0.0.1',8080),MyTcp)
server.serve_forever()
客户端是一样的。
不同的地方是,这里的self.request就相当于之前建立的通道,也就是conn。
以上是tcp版的
接下来是udp版本的。
server端
import socketserver
class MyUdp(socketserver.BaseRequestHandler):
def handle(self):
self.request[1].sendto('xxxx'.encode('utf8'),self.client_address)
if __name__ == '__main__':
server=socketserver.ThreadingUDPServer(('127.0.0.1',8080),MyUdp)
server.serve_forever()
同样的,客户端也是一样的。
这里的request对象是一个元组,第一个元素是接受到的数据,第二个数据才是发送数据的。