socket是利用多线程来完成并发操作,tcp协议一次性只能接受一个客户端,所以需要利用多线程来同时接收多个客户端,
利用socketserver模块来实现并发操作。
1.TCP多线程
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
import socketserver ip_port=('127.0.0.1',8080) class Myserver(socketserver.BaseRequestHandler): def handle(self):#一定要重新定义一个hundle #self.request====con # self.client_address==addr while 1:#收发循环 try: data=self.request.recv(1024)#接收数据 print('客户端发来的消息是:',data) self.request.sendall(data.upper()) except Exception:#如果出现异常 break if __name__ == '__main__': s=socketserver.ThreadingTCPServer(ip_port,Myserver) s.serve_forever()
2.UDP多线程
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
import socketserver ip_port=('127.0.0.1',8080) #和TCP不同的是,方法的意义 #在UDP中 # self.request====(data,self.socket) # self.client_address=======udp客户端的地址 class Myserver(socketserver.BaseRequestHandler): def handle(self):#一定要重新定义一个hundle #self.request====con # self.client_address==addr # while 1:#收发循环#对于UDP来说,就不需要循环这个过程了,自动会收发,不需要建立连接 data=self.request[0]#第一个参数就是接收的数据 print('客户端发来的消息是:',data) self.request[1].sendto(data.upper(),self.client_address) if __name__ == '__main__': s=socketserver.ThreadingUDPServer(ip_port,Myserver) s.serve_forever()
其实udp没有这个操作也可以实现多用户,因为本身就是不建立在链接的基础上。
3.socket源码分析
主要有两点,
对于tcp的多线程来说,self.request就是本身服务端的conn,也就是和客户端建立的这个链接,self.client_addrsss就是和客户端建立链接的地址
对于UDP的多线程来说。self.request====(data,self.socket),其中第一个数据是从客户端收到的数据,第二个数据是通过socket建立的对象。可以对这个对象进行操作,比如self.socket.sendto(data,addr),另外self.client_address就是addr,也就是客户端建立的连接。
如果真的追溯源头的话,还需要对源码进行查看,分清楚各个类的继承关系,最后找到这几个关键的信息。