153*_*957 7 python sockets timeout urllib2 http-post
我正在使用Python 2.7.1 urllib2包中的urlopen从Windows XP机器到远程Apache Web服务器(例如Mac OS X的内置Web共享)执行HTTP POST.发送的数据包含一些标识符,数据和校验和,如果发送了所有数据,则服务器以确认响应.数据中的校验和可用于检查一切是否按顺序到达.
通常这很好用,但有时互联网连接不好,通常是因为发送数据的客户端使用wifi或3G连接.这导致互联网连接丢失一段任意时间.urlopen包含一个超时选项,以确保它不会阻止您的程序,它可以继续.
这就是我想要的,但问题是urlopen不会阻止套接字继续发送超时发生时仍然必须发送的任何数据.我通过尝试向我的笔记本电脑发送大量数据来测试这个(我将在下面显示的代码),我会在两个show activity上看到网络活动,然后我会在笔记本电脑上停止无线,等待直到该功能超时,然后重新激活无线,然后数据传输将继续,但程序将不再监听响应.我甚至试图退出Python解释器,它仍然会发送数据,因此控制权以某种方式传递给Windows.
超时(据我所知)的工作方式如下:它检查'空闲响应时间'
([Python-Dev]将套接字超时添加到urllib2)
如果将超时设置为3,它将打开连接,启动计数器然后尝试发送数据并等待响应,如果在接收响应之前的任何时刻计时器用完,则调用超时异常.请注意,就超时计时器而言,发送数据似乎不算作"活动".
(urllib2超时但没有关闭套接字连接)
(关闭urllib2连接)
显然它是在某个地方陈述当套接字被关闭/解除引用/垃圾收集时它调用它的'close'函数,它等待在关闭套接字之前发送所有数据.但是还有一个关闭功能,它应该立即停止套接字,防止发送更多数据.
(socket.shutdown vs socket.close)
(http://docs.python.org/library/socket.html#socket.socket.close)
我希望在发生超时时连接为"关闭".否则,我的客户将无法判断数据是否已正确接收,并且可能会尝试再次发送.我宁愿直接杀死连接并稍后再试,因为知道数据(可能)没有成功发送(如果校验和不匹配,服务器可以识别这个).
这是我用来测试它的代码的一部分.try..except部分还没有像我期望的那样工作,任何帮助也有所值得赞赏.正如我之前所说,我希望程序在引发超时(或任何其他)异常时立即关闭套接字.
from urllib import urlencode
from urllib2 import urlopen, HTTPError, URLError
import socket
import sys
class Uploader:
def __init__(self):
self.URL = "http://.../"
self.data = urlencode({'fakerange':range(0,2000000,1)})
print "Data Generated"
def upload(self):
try:
f = urlopen(self.URL, self.data, timeout=10)
returncode = f.read()
except (URLError, HTTPError), msg:
returncode = str(msg)
except socket.error:
returncode = "Socket Timeout!"
else:
returncode = 'Im here'
def main():
upobj = Uploader()
returncode = upobj.upload()
if returncode == '100':
print "Success!"
else:
print "Maybe a Fail"
print returncode
print "The End"
if __name__ == '__main__':
main()
Run Code Online (Sandbox Code Playgroud)
事实证明,在正在上传的 HTTPConnection 上调用 .sock.shutdown(socket.SHUT_RDWR) 和 .close() 命令不会停止上传。它将继续在后台运行。在使用 urllib2 或 httplib 时,我不知道有更可靠/直接的方法来终止来自 Python 的连接。
最后我们测试了使用urllib2上传没有超时。这意味着在连接速度较慢的情况下,上传(POST)可能需要很长时间,但至少我们会知道它是否有效。由于没有超时,urlopen 可能会挂起,但我们测试了各种连接不良的可能性,在所有情况下,urlopen 要么工作正常,要么在一段时间后返回错误。
这意味着我们至少会在客户端知道上传成功或失败,并且不会在后台继续。
| 归档时间: |
|
| 查看次数: |
2027 次 |
| 最近记录: |