您的位置:首页 > 理论基础 > 计算机网络

Python网络编程之多线程服务端

2010-02-21 10:51 471 查看
前面实现的两个服务端有一个共同的问题就是:一次只允许一个客户端连接。如果你打开两个 telnet 会话来连接同一个服务端, 那么第二个会话只有在关闭第一个会话之后才能连接上。如果一个实际的服务端像这个工作,那么什么事都将做不了。这就是为什么大部分实际的服务端都采用线程或子进程来处理多个连接。

SocketServer 模块定义了两个有用的类来处理多个连接:ThreadingMixIn 和 ForkingMixIn 。一个继承自 ThreadingMixIn 的 SocketServer 类会对每个进来的请求自动产生一个新的线程来处理。而继承自 ForkingMixIn 的子类对每个进来的请求将会自动产生一个新的子进程。个人喜欢 ThreadingMixIn 更甚一点,因为线程比子进程更高效和易移植。同时线程与父线程的通信也比采用子进程来得得更加的容易。

下面是 MultithreadedMirrorServer.py ,它是 MirrorSocketServer 的多线程版本。注意到它跟 MirrorSocketServer.py 都使用一个同一个类 RequestHandler 。所不同的是,在这里我们不再使用 TCPServer 而采用 ThreadingTCPServer ——从 ThreadingMixIn 和 TCPServer 继承的标准类:

MulitithreadedMirrorServer#!/usr/bin/python
import SocketServer

class RequestHandler(SocketServer.StreamRequestHandler):
"Handles one request to mirror some text."

def handle(self):
"""Read from StreamRequestHandler's provided rfile member,
which contains the input from the client. Mirror the text
and write it to the wfile member, which contains the output
to be sent to the client."""
l = True
while l:
l = self.rfile.readline().strip()
if l:
self.wfile.write(l[::-1] + '\n')

if __name__ == '__main__':
import sys
if len(sys.argv) < 3:
print 'Usage: %s [hostname] [port number]' % sys.argv[0]
sys.exit(1)

hostname = sys.argv[1]
port = int(sys.argv[2])
server = SocketServer.ThreadingTCPServer((hostname, port), RequestHandler)
server.serve_forever()


运行这个服务端,你可以同时运行大堆的 telnet 和 MirrorClient 会话。就像 TCPServer 将 sockets 的细节隐藏, ThreadingMixIn 也隐藏了线程产生的细节。这个类的主要目标是为了让你能够专心地处理从网络上接收和发送的数据。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: