published on in Python

网络篇・TCP通信

返回教程主页

上篇 网络篇・Web爬虫

现在我们要实现一个服务器,通过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'
>>>

下篇 网络篇・UDP通信