简体   繁体   English

在python中挂起http POST请求该怎么办?

[英]What should I do with hanging http POST request in python?

Sample code: 样例代码:

socket.setdefaulttimeout(150)

MechBrowser = mechanize.Browser()
Header = {'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 GTB7.1 (.NET CLR 3.5.30729)'}
Url = "http://example.com"
Data = "Justatest=whatever&letstry=doit"
Request = urllib2.Request(Url, Data, Header)
Response = MechBrowser.open(Request)
Response.close()

I don't think there's anything wrong with above codes, but every now and then I'll get hanging http POST request which prevents the whole script from continuously running. 我不认为上面的代码有什么问题,但是我时不时地会挂起http POST请求,这会阻止整个脚本连续运行。 I already used socket.setdefaulttimeout(150) how come it's not working? 我已经使用过socket.setdefaulttimeout(150)怎么不起作用? What is the reason causing this problem? 造成此问题的原因是什么? And what should I do to get rid of this? 我应该怎么做才能摆脱这种情况?

Found the problem. 找到了问题。

I've been using requests a lot recently and realized that the timeout you set in both mechanize and requests are "NOT a time limit on the entire response download" , which means if the connection is really slow and there are still data transferring, it will not timeout, which could hang the connection for quite a long time. 我最近一直在使用requests并且意识到在mechanizerequests中设置的timeout“对于整个响应下载没有时间限制” ,这意味着如果连接速度很慢并且仍然有数据传输,它不会超时,这可能会使连接挂起很长时间。

So what I've done is wrap those requests with threads and set timeout for those threads, and this way timeout is more accurate, just make sure you clean up/garbage collect those hanging connections. 因此,我要做的是用线程包装这些请求,并为这些线程设置超时,这样超时就更准确了,只要确保您清理/垃圾收集那些挂起的连接即可。

Could be many reasons - the server that you are posting to could be busy, network congestion, etc. 可能有很多原因-您要发布到的服务器可能很忙,网络拥塞等。

However, you can eliminate problems from your end by making sure you send complete headers (you are missing Content-type header). 但是,可以通过确保发送完整的标头(丢失了Content-type标头)来从头解决问题。

i think it's because you didn't set content-length header. 我认为这是因为您没有设置content-length标头。 if a request is posted to the server, the data are submitted in the request's body. 如果将请求发布到服务器,则数据将在请求的正文中提交。 due to tcp connection 's streaming based characteristics, there's no way for the server to find out the length of request, unless you tell it explicitly in header. 由于tcp connection基于流的特性,除非您在标头中明确告知请求,否则服务器无法找出请求的长度。 without knowing when your request is end , the server has to wait indefinitely. 在不知道您的请求何时结束的情况下,服务器必须无限期地等待。

and the timeout attribute doesn't work here because your socket isn't blocked on any recv/send operation. 并且timeout属性在这里不起作用,因为您的套接字未在任何recv / send操作上被阻止。 you've done writing data through socket, but the server thinks you have more to send. 您已经完成了通过套接字写入数据的操作,但是服务器认为您还有更多要发送的数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM