socketserver模块实现并发

## socketserver模块实现并发(利用多线程)

**jason版socketserver**
**TCP的socketserver**
服务端
```python
import socketserver

class MyServer(socketserver.BaseRequestHandler):
def handle(self):
# print('来啦 老弟')
while True:
data = self.request.recv(1024)
print(self.client_address) # 客户端地址
print(data.decode('utf-8'))
self.request.send(data.upper())

if __name__ == '__main__':
"""只要有客户端连接 会自动交给自定义类中的handle方法去处理"""
server = socketserver.ThreadingTCPServer(('127.0.0.1',8080),MyServer) # 创建一个基于TCP的对象
server.serve_forever() # 启动该服务对象
```
客户端(连续开多个客户端进行验证)
```python
import socket

client = socket.socket()
client.connect(('127.0.0.1',8080))

while True:
client.send(b'hello')
data = client.recv(1024)
print(data.decode('utf-8'))
```

**UDP的socketserver**
服务端
```python
import socketserver

class MyServer(socketserver.BaseRequestHandler):
def handle(self):
# print('来啦 老弟')
while True:
data,sock = self.request
print(self.client_address) # 客户端地址
print(data.decode('utf-8'))
sock.sendto(data.upper(),self.client_address)

if __name__ == '__main__':
"""只要有客户端连接 会自动交给自定义类中的handle方法去处理"""
server = socketserver.ThreadingUDPServer(('127.0.0.1',8080),MyServer) # 创建一个基于TCP的对象
server.serve_forever() # 启动该服务对象
```
客户端(连续开多个客户端进行验证)
```python
import socket
import time

client = socket.socket(type=socket.SOCK_DGRAM)
server_address = ('127.0.0.1',8081)

while True:
client.sendto(b'hello',server_address)
data,addr = client.recvfrom(1024)
print(data.decode('utf-8'),addr)
#睡一秒,不然速度太快,收不到其余客户端的消息
time.sleep(1)
```
* * *

* * *

* * *
**egon版socketserver**
服务端:来一个连接就产生一个ThreadingTCPServer实例
```python
import socketserver
class MyServer(socketserver.BaseRequestHandler):
# 描述如何进行服务
def handle(self):
print('conn is: ',self.request) #相当于conn
print('addr is: ',self.client_address) #相当于addr
#循环监听(读取)来自客户端的数据
while True:
try:
#收消息
data=self.request.recv(1024)
if not data:break
print('收到客户端的消息是',data,self.client_address)

#发消息
self.request.sendall(data.upper())

except Exception as e:
print(e)
break
#以上为通信循环
if __name__ == '__main__':
#传一个ip_port,一个带有方法的类
#ThreadingTCPServer相当于链接循环类 MyServer相当于通信循环类,套在链接循环中
#把(ip_port,描述了具体服务的类)传给链接循环类,产生实例
s=socketserver.ThreadingTCPServer(('127.0.0.1',8080),MyServer) #多线程
# s=socketserver.ForkingTCPServer(('127.0.0.1',8080),MyServer) #多进程

# self.server_address = server_address
# self.RequestHandlerClass = RequestHandlerClass
print(s.server_address)
print(s.RequestHandlerClass)
print(MyServer)
print(s.socket)
print(s.server_address)
s.serve_forever()
```

客户端
```python
from socket import *
ip_port=('192.168.12.63',8080)
back_log=5
buffer_size=1024

tcp_client=socket(AF_INET,SOCK_STREAM)
tcp_client.connect(ip_port)

while True:
msg=input('>>: ').strip()
if not msg:continue
if msg == 'quit':break

tcp_client.send(msg.encode('utf-8'))

data=tcp_client.recv(buffer_size)
print('收到服务端发来的消息:',data.decode('utf-8'))

tcp_client.close()
```
33daad7cdce8c3cba71b83fed189b0bc.png  
ee95e35e7d07b06fdd9cc6ef7893e0d9.png  
3b4c8aa16ece6b0cc1546ff60753e9aa.png  
888b16167f38cc878a6d14e320fc571a.png  
7b895c5621b5d1a6f4e945ee6c7b8f5d.png  

涉及很多继承,函数的例子
TCP服务端
```python
import socketserver
class MyServer(socketserver.BaseRequestHandler):
# 来一个连接就产生一个实例
def handle(self):
print('conn is: ',self.request) #相当于conn
print('addr is: ',self.client_address) #相当于addr
#循环监听(读取)来自客户端的数据
while True:
try:
#收消息
data=self.request.recv(1024)
if not data:break
print('收到客户端的消息是',data,self.client_address)

#发消息
self.request.sendall(data.upper())

except Exception as e:
print(e)
break
#以上为通信循环
if __name__ == '__main__':
#socketserver.allow_reuse_address=True是否可防止地址报错???
#传一个ip_port,一个类
#ThreadingTCPServer相当于链接循环类 MyServer相当于通信循环类,套在链接循环中
#把ip_port,含有处理通信方法的类,传给ThreadingTCPServer类,产生实例
s=socketserver.ThreadingTCPServer(('127.0.0.1',8083),MyServer) #多线程
'''
现在s成为一个s.socket即为套接字,
s.RequestHandlerClass即MyServer类
s.serve_forever()即可产生链接循环的实例
证明:
self.server_address = server_address
self.RequestHandlerClass = MyServer
ThreadingTCPServer实例化的s包含的东西
print(s.server_address) #就是('127.0.0.1',8080)
print(s.RequestHandlerClass) #就是MyServer
print(MyServer) # 同上
print(s.socket) # socket实例
print(s.server_address) #
'''
print(s.RequestHandlerClass.handle())
s.serve_forever()
'''
此处有循环,且循环执行s.socket.accept()
故得到conn,addr=s.socket.accept() 即产生了conn

得到链接后就要利用MyServer的实例来进入通讯循环了
s.RequestHandlerClass(conn,addr,s)即MyServer(conn,addr,s)
查过源码s传给MyServer其实没有什么意义,MyServer实例并未用s执行任何代码
'''
#s=socketserver.ForkingTCPServer(('127.0.0.1',8080),MyServer) #多进程

#s.RequestHandlerClass(x,y,z).handle()即可执行

'''
整个逻辑的最后,MyServer实例化,会触发handle()即自定义的服务
def __init__(self, request, client_address, server):
self.request = request
self.client_address = client_address
self.server = server
self.setup()
try:
self.handle()
finally:
self.finish()
'''
```
UDP服务端
```python
import socketserver

class MyServer(socketserver.BaseRequestHandler):
def handle(self):
print(self.request)
print('收到客户端的消息是',self.request[0])
self.request[1].sendto(self.request[0].upper(),self.client_address)


if __name__ == '__main__':
s=socketserver.ThreadingUDPServer(('127.0.0.1',8080),MyServer) #多线程
s.serve_forever()
```
验证客户端合法性
[https://www.cnblogs.com/linhaifeng/articles/6129246.html#_label13](https://www.cnblogs.com/linhaifeng/articles/6129246.html#_label13)

 

posted @ 2019-08-14 19:00  坚持fighting  阅读(179)  评论(0编辑  收藏  举报