黑马程序员技术交流社区
标题:
【上海校区】python 之socketserver模块可以更方便地建立TCP,UDP服务器
[打印本页]
作者:
范志远
时间:
2018-5-21 19:10
标题:
【上海校区】python 之socketserver模块可以更方便地建立TCP,UDP服务器
1.socketserver模块
2.步骤及代码
3.socketserver框架实现多线程服务器
1.socketserver模块
socketserver是python 的一个网络服务器框架,可以减少编写网络服务器程序的工作量。
socketserver模块只能用来写服务端
socketserver模块中使用的服务器类主要有 : TCPserver,UDPserver,ThreadingTCPserver,ThreadingUDPserver,ForkingTCPserver,ForkingUDPserver
有TCP字段的表示TCP协议服务器,有UDP字段的表示UDP协议服务器,有Threading字段的表示多线程,有Forking字段的表示多进程
socketserver模块中使用的处理器类主要有 : StreamRequestHandler(基于TCP协议) , DatagramRequestHandler(基于UDP协议)。处理器类中有一个十分重要的方法:handler() 。 处理器类用来做什么操作都是写在handler()里的
[python] view plain copy
1. class myTcp(socketserver.StreamRequestHandler): #继承TCP的处理器类
2. def handle(self):
3. xxx #myTcp这个类要做的操作写在handler()里
工作模式:
socketserver 框架 分为两大类操作,一是 服务器类(就是上面的TCPserver,UDPserver等等),二是处理器类,处理器类用于处理数据接收或者传送,而服务器类用于处理客户端和服务端通信问题 。
只要继承其中一个处理器类(TCP 或 UDP),就可以自定义一个处理器类(自定义数据如何传送或接收)
2.步骤及代码
1.选择一个服务器类,并创建其对象(如对象叫 server)。
2.自定义处理器类(或叫请求类)的功能
3.调用对象(server)的serve_forever() 方法 来 启动服务器
基于socketserver 的TCP服务端
[python] view plain copy
1. from socketserver import StreamRequestHandler as Tcp #选择 TCP的处理器类
2. import socketserver
3. host=''
4. port = 8888
5. addr = (host,port)
6.
7. '''''处理器类部分'''
8. class myTcp(Tcp): #第二步:自定义处理器类的功能(这也是一个请求--request)
9. def handle(self):
10. print('client\'s address:',self.client_address), #打印连接上的客户端的 ip地址
11. while True:
12. data = self.request.recv(1024) #从客户端接收信息
13. if not data:
14. break
15. print(data.decode('utf-8'))
16. self.request.sendall(data) #向客户端发送信息
17.
18. if __name__ == '__main__':
19. '''''服务器类部分'''
20. server = socketserver.TCPServer(addr,myTcp) #第一步:.选择一个服务器类,并创建其对象
21. server.serve_forever() #第三步:开启服务器
客户端代码:
[python] view plain copy
1. from socket import *
2.
3. host ='localhost'<span style="white-space:pre;"> </span>#我是本机操作,所以host写localhost,如果是连接外部的服务器,host就要等于服务器的ip地址
4. port =8888
5. bufsize = 1024
6. addr = (host,port)
7. client = socket(AF_INET,SOCK_STREAM)
8. client.connect(addr)
9. while True:
10. data = input()
11. if not data or data=='exit':
12. break
13. client.send(data.encode('utf-8'))
14. data = client.recv(bufsize)
15. if not data:
16. break
17. print (data.decode('utf-8'))
18. client.close()
基于 socketserver 的 UDP服务端代码:
[python] view plain copy
1. from socketserver import DatagramRequestHandler as udp #选择 UDP的处理器类
2. import socketserver
3. host=''
4. port = 8888
5. addr = (host,port)
6.
7. '''''处理器类部分'''
8. class myUDP(udp): #第二步:自定义处理器类的功能(这也是一个请求--request)
9. def handle(self):
10. print('client\'s address:',self.client_address), #打印连接上的客户端的 ip地址
11. while True:
12. data = self.rfile.readline() #读取客户端发来的信息
13. if not data:
14. break
15. print(data.decode('utf-8'))
16. self.wfile.write(data) #向客户端发送信息
17.
18. if __name__ == '__main__':
19. '''''服务器类部分'''
20. server = socketserver.UDPServer(addr,myUDP) #第一步:.选择一个服务器类,并创建其对象
21. server.serve_forever() #第三步:开启服务器
UDP客户端:
[python] view plain copy
1. from socket import *
2.
3. host ='localhost'
4. port =8888
5. bufsize = 1024
6. addr = (host,port)
7. client = socket(AF_INET,SOCK_DGRAM)
8.
9. while True:
10. data = input()
11. if not data or data=='exit':
12. break
13. client.sendto(data.encode('utf-8'),addr)
14. data,saddr= client.recvfrom(bufsize)
15. if not data:
16. break
17. print (data.decode('utf-8'))
18. client.close()
3.用socketserver框架实现多线程服务器
Threading.TCPServer(服务类) + StreamRequesetHandler(处理类或叫请求类) = TCP多线程服务器
多线程 TCP 服务端:
[python] view plain copy
1. from socketserver import ThreadingTCPServer, StreamRequestHandler
2.
3. class myTCP(StreamRequestHandler):
4. def handle(self):
5. while True:
6. data = self.request.recv(1024)
7. print ("receive from (%r):%r" % (self.client_address, data))
8. self.wfile.write(data)
9.
10. if __name__ == "__main__":
11. host = "" #主机名,可以是ip,像localhost的主机名,或""
12. port =8888 #端口
13. addr = (host, port)
14.
15. server = ThreadingTCPServer(addr, myTCP) #实例化一个 多线程TCP服务类
16. server.serve_forever() #开启
上面的代码运行后,就可以接受多个客户端发来的连接和信息。(客户端代码可以用 TCP客户端代码,文章有)
上面的代码还是有缺憾的,就是这个程序就只能运行一个多线程TCP。
下面我们试试,一个程序除了运行 一个多线程TCP外,还可以用其他多线程运行其他任务(如:计数任务)
[ 一个程序运行 多个不同功能的线程 ]
[python] view plain copy
1. from socketserver import ThreadingTCPServer, StreamRequestHandler
2. import socketserver
3. import threading
4. import time
5.
6. '''''线程任务1'''
7. class myTCP(StreamRequestHandler): #TCP处理器类(或叫请求类) 在这里 作为一个 线程任务
8. def handle(self):
9. while True:
10. data = self.request.recv(1024)
11. print ("receive from (%r):%r" % (self.client_address, data))
12. self.wfile.write(data)
13.
14. '''''线程任务2'''
15. class Count(threading.Thread): #另一个线程任务,用于计数,暂且叫他计数线程
16. count = 0
17. def run(self):
18. while True:
19. self.count += 1
20. print('count = ',self.count)
21. time.sleep(1)
22.
23. if __name__ == "__main__":
24. host = ""
25. port =8888
26. addr = (host, port)
27.
28. '''''实现一个多线程TCP服务器'''
29. server = ThreadingTCPServer(addr,myTCP) #实例化一个多线程TCP服务器类
30. server_thread = threading.Thread(target=server.serve_forever) #创建线程,线程用于TCP多线程
31. server_thread.start() #开启线程
32.
33. '''''实现循环计数'''
34. count_thread = Count() #创建计数线程
35. count_thread.start() #开启线程
作者:
似景
时间:
2018-5-23 09:20
作者:
吴琼老师
时间:
2018-7-5 16:49
作者:
不二晨
时间:
2018-7-10 14:54
奈斯
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2