现在我们要实现一个服务器,通过TCP协议与客户端程序通讯。
socketserver
我们使用Python的socketserver
库就可以快速实现一个简单的应答服务器:
from socketserver import BaseRequestHandler, TCPServer
class EchoHandler(BaseRequestHandler):
def handle(self):
print('Got connection from', self.client_address)
while True:
msg = self.request.recv(8192)
if not msg:
break
self.request.send(msg)
if __name__ == '__main__':
serv = TCPServer(('', 8000), EchoHandler)
serv.serve_forever()
在这段代码中,我们定义了一个特殊的处理类EchoHandler
,实现了一个handle()
方法,用来为客户端连接服务。self.request
属性用于获处理客户端socket,client_address
为客户端地址。将EchoHandler
传给TCPServer
并指定8000
端口号,我们就能得到一个服务器实例serv
,运行方法serv.serve_forever
可以启动它「如果想关停可以在命令行中敲击快捷键ctrl + c
」。
为了测试这个服务器,我们还需要创建客户端socket去连接它:
>>> from socket import socket, AF_INET, SOCK_STREAM
>>> s = socket(AF_INET, SOCK_STREAM)
>>> s.connect(('localhost', 8000))
>>> s.send('Hello'.encode())
5
>>> s.recv(8192).decode()
'Hello'
>>>
ThreadingTCPServer
TCPServer
可以快速实现一个简单的服务器,但默认情况下只会得到一个单线程的服务器,不能同时连接多个客户端。使用ThreadingTCPServer
则可以快速实现多线程的服务器:
from socketserver import BaseRequestHandler
from socketserver import ThreadingTCPServer
class EchoHandler(BaseRequestHandler):
def handle(self):
print('Got connection from', self.client_address)
while True:
msg = self.request.recv(8192)
if not msg:
break
self.request.send(msg)
if __name__ == '__main__':
serv = ThreadingTCPServer(('', 8000), EchoHandler)
serv.serve_forever()
使用两个客户端socket进行测试:
>>> s1 = socket(AF_INET, SOCK_STREAM)
>>> s2 = socket(AF_INET, SOCK_STREAM)
>>> s1.connect(('localhost', 8000))
>>> s2.connect(('localhost', 8000))
>>> s1.send(b'Hello1')
6
>>> s2.send(b'Hello2')
6
>>> s1.recv(8192)
b'Hello1'
>>> s2.recv(8192)
b'Hello2'
>>>