这里的问题是,在中TCPHandler
,“请求”实际上是从头到尾的完整连接。*您的处理程序被调用accept
,从中返回时,套接字被关闭。
如果要在此之上构建一个请求-响应- 协议处理程序,该处理程序在单个套接字级请求上处理多个协议级请求,则您必须自己执行此操作(或使用更高级别的框架)。(类似的子类BaseHTTPServer
演示了如何执行此操作。)
例如,您可以在handle
函数中使用循环。当然,您可能想要在此处添加一个异常处理程序和/或处理EOF fromrfile
(注释self.rfile.readline()
将返回''
EOF,但返回'\n'
空行,因此您必须在调用前进行检查,strip
除非您希望空行表示“退出”在您的协议中)。例如:
def handle(self):
try:
while True:
request = self.rfile.readline()
if not request:
break
request = request.rstrip()
print "RX [%s]: %s" % (self.client_address[0], request)
response = self.processRequest(request)
print "TX [%s]: %s" % (self.client_address[0], response)
self.wfile.write(response + '\n')
except Exception as e:
print "ER [%s]: %r" % (self.client_address[0], e)
print "DC [%s]: disconnected" % (self.client_address[0])
这 通常 可以与您现有的客户端一起使用,至少可以在已卸载的计算机上通过localhost进行,但这实际上是不正确的,而且“经常工作”通常还不够好。请参阅TCP套接字是字节流,而不是消息流,以进行更长时间的讨论,但简要地说,您 还 需要执行David Schwarz的回答中提到的内容:将新行添加到从服务器写入的内容(我已经在上面做过)了,并具有客户端逐行读取,而不是一次尝试读取1024个字节(您可以通过编写自己的缓冲区和分割行代码或仅通过使用makefile
方法来做到这一点,因此它可以rfile.readline()
像服务器一样使用边做。)
不修复客户端不会引起回答索赔的问题,但是 会 引起如下问题:
Sent: request type 01
Received: resp
Sent: request type 02
Received: onse type 01
response typ
您会看到,在一个实际试图以编程方式处理响应的真实程序中,类似resp
或onse type 01\nresponse typ
将不会非常有用的响应…
*请注意,这SocketServer
是一个没人真正喜欢的古老设计。有一个添加Python 3的原因asyncio
,并且Python 2中的人通常使用Twisted和gevent之类的第三方框架。对于简单任务,它们既简单,又对复杂任务更灵活/强大(并且效率更高)。