2012-03-05 74 views
4

后,我写了一个简单的服务器,它扩展了SimpleHTTPRequestHandler蟒蛇SimpleHTTPRequestHandler服务器离开插座TIME_WAIT状态退出

如果我启动和停止它,而无需对服务器进行任何请求,我可以在同一个端口上启动备份没有问题。

启动时,一个netstat的看起来是这样的:一个请求时

 
[email protected]:server$ sudo netstat -na --program | grep 8001 
tcp  0  0 0.0.0.0:8001   0.0.0.0:*    LISTEN  23392/python 

后,netstat的看起来像这样(请求完成后也):

 
[email protected]:server$ sudo netstat -na --program | grep 8001 
tcp  0  0 0.0.0.0:8001   0.0.0.0:*    LISTEN  23392/python  
tcp  0  0 127.0.0.1:8001   127.0.0.1:48659   TIME_WAIT - 

然后,我杀使用Cc和netstat的服务器看起来像这样(此时由于端口已被使用,我无法重新启动服务器):

 
sudo netstat -na --program | grep 8001 
tcp  0  0 127.0.0.1:8001   127.0.0.1:48674   TIME_WAIT - 

我显然不能正确地关闭某些东西。我发送回复的代码如下所示:

""" 
reply is an object that can be json encoded that is written with a response code 200 
""" 
def send_provider_reply(self, replyobj): 
    try: 
     str_reply = json.dumps(replyobj) 
     self.send_response(200) 
     self.send_header('Content-type', 'application/json') 
     self.end_headers() 
     #do we need to send a newline?? 
     self.wfile.write(str_reply) 
    except: 
     traceback.print_exc() 
     self.send_err(500, 'failed after provider creation') 

回答

5

套接字选项SO_LINGER确实会阻止套接字进入TIME_WAIT。但是TIME_WAIT的存在是有原因的:它应该保护你免受旧连接的延迟包裹。因此,TIME_WAIT的默认持续时间是网络往返的两倍。因此,在TIME_WAIT中找到一些较旧的连接是正常的。

给一些上下文:在服务器端,使用侦听套接字,有SO_REUSEADDR套接字选项。它允许侦听套接字在TIME_WAIT结束之前成功绑定。对于服务器进程,它总是应该监听同一个端口(想想:在端口80,443处的webserver),这是必须的。对于服务器

典型的Python代码可能包含这样的事情:

... 
listener = socket(AF_INET, SOCK_STREAM) 
listener.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) 
listener.bind((HOST, PORT)) 
listener.listen(32) 
... 
+0

我想我跟着你从挥之不去的分组部的保护,但我不明白为什么这是一件好事:“它允许侦听套接字在TIME_WAIT结束之前成功绑定“。我知道可以快速停止/启动的其他服务器(例如nginx),他们做了什么来避免这种情况?谢谢! – Hersheezy 2012-03-06 03:22:25

+0

他们使用SO_REUSEADDR。 – 2012-03-06 07:30:33