socketserver的使用(并发)
基于tcp的套接字,关键就是两个循环,一个链接循环,一个通信循环
socketserver模块中分两大类:server类(解决链接问题)和request类(解决通信问题)
源码分析
socketserver源码分析
- ThreadingTCPServer :init:创建socket,bind,listen
- server.serve_forever() :创建线程,建立连接,和处理通信
基本使用
tcp的服务端
- server=ThreadingTCPServer 对象
- server.serve_forever
- 写一个类,类里重写handle,方法内收发数据(并发起来了)
udp的服务端
- server=ThreadingUDPServer 对象
- server.serve_forever
- 写一个类,类里重写handle,方法内收发数据(并发起来了)
self.request(tcp/udp是不一样的)
self.client_address 客户端地址
socketserver-TCP
'''
可同时开多个client端与server端连接
每当有一个client与server端发送连接请求时,就会创建一个线程来处理client的请求,并与其交互。
'''
# server
import socketserver
addr = ('127.0.0.1',8080)
# 自定义一个类,必须继承socketserver.BaseRequestHandler
class Mytcp(socketserver.BaseRequestHandler):
# 必须重写handle方法,里面写主要的逻辑代码
def handle(self):
try:
while True:
# self.request就相当于之前的conn
data = self.request.recv(1024).decode('utf8')
print(data)
if len(data) == 0:
return
msg = input('>>>')
msg = '来自主机:'+ msg
self.request.send(msg.encode('utf8'))
except Exception:
pass
if __name__ == '__main__':
# 实例化得到一个tcp连接的对象,Threading意思是,只要来了请求,它自动开一个线程来处理并进行交互
# 第一个参数是绑定的地址,第二个参数的传一个类
sk = socketserver.ThreadingTCPServer(addr,Mytcp)
sk.serve_forever()
# client
import socket
sk = socket.socket()
addr = ('127.0.0.1',8080)
sk.connect(addr)
while True:
msg = input('>>>:')
msg = '来自client(one):' + msg
sk.send(msg.encode('utf8'))
print(sk.recv(1024).decode('utf8'))
socketserver-UDP
# server
import socketserver
addr = ('127.0.0.1',10000)
class MyUdp(socketserver.BaseRequestHandler):
def handle(self):
# print(self.request) # 元组
# print(self.request[0]) # client端发送过来的数据
# print(self.request[1]) # socket对象
data = '来自主机:'+ self.request[0].decode('utf8')
print(data)
msg = input('>>>:')
self.request[1].sendto(msg.encode('utf8'), self.client_address)
if __name__ == '__main__':
sk = socketserver.ThreadingUDPServer(addr,MyUdp)
sk.serve_forever()
# client
import socket
sk = socket.socket(type=socket.SOCK_DGRAM)
addr = ('127.0.0.1',10000)
while True:
msg = input('>>>:')
msg = '来自client(1):' + msg
sk.sendto(msg.encode('utf8'), addr)
data,addr = sk.recvfrom(1024)
print(data.decode('utf8'))