Python Sockets,下载几乎是原始文件大小的 10 倍,上传是 0 字节
Posted
技术标签:
【中文标题】Python Sockets,下载几乎是原始文件大小的 10 倍,上传是 0 字节【英文标题】:Python Sockets, download is almost 10x the size of original file, upload is 0 bytes 【发布时间】:2014-08-29 02:22:43 【问题描述】:使用嵌入式 Python 2.7 创建移动应用程序
使用 Marmalade C++ SDK。
我正在集成与云文件传输服务的连接。
FTP:文件传输完美无缺 Dropbox:验证然后给我:socket [Errno 22] Invalid argument Google 云端硬盘:进行身份验证、列出元数据,但文件传输存在一些奇怪的非法行为由于我已经对 marmalade 套接字子系统(类似 unix)进行了所有绑定,但有些功能没有实现。为了连接到 Google Drive,最初我对 httplib2 / init.py 做了一些修改,设置了以下所有实例:
self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
#to this:
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
完成这个小补丁后,我可以成功连接并从 Google Drive 下载元数据。然而:
当我上传一个 7KB 的文件时,该文件出现在 Google Drive 上,但有一个 文件大小为 0 字节 当我使用 urllib 下载一个 7KB 的文件时,我得到一个 54KB 文件返回我知道这一定与套接字属性的错误配置有关,但并非所有属性都已实现。 Here are some standard python test outputs (test_sockets , test_httplib )
这里的实现: Marmalade /h/std/netdb.h
有什么我应该尝试的可行替代品吗?
我不知道。
From: unix-man setsockopt(2)
SO_DEBUG enables recording of debugging information
SO_REUSEADDR enables local address reuse
SO_REUSEPORT enables duplicate address and port bindings
SO_KEEPALIVE enables keep connections alive
SO_DONTROUTE enables routing bypass for outgoing messages
SO_LINGER linger on close if data present
SO_BROADCAST enables permission to transmit broadcast messages
SO_OOBINLINE enables reception of out-of-band data in band
SO_SNDBUF set buffer size for output
SO_RCVBUF set buffer size for input
SO_SNDLOWAT set minimum count for output
SO_RCVLOWAT set minimum count for input
SO_SNDTIMEO set timeout value for output
SO_RCVTIMEO set timeout value for input
SO_ACCEPTFILTER set accept filter on listening socket
SO_TYPE get the type of the socket (get only)
SO_ERROR get and clear error on the socket (get only)
Here is my Google upload / download / listing source code
希望在问题解决之前,我会强制执行此操作。如果我弄明白了,我会回来报告的
【问题讨论】:
你的描述很混乱。带有 TCP_NODELAY 的原始版本和带有 SO_REUSEADDR 的原始版本基本上与所描述的问题无关。 TCP_NODELAY 只能提高交互交换速度,但 HTTP 并不需要它。 SO_REUSEADDR 不影响连接,只影响端口绑定。我认为要诊断问题,您应该捕获网络流量并对其进行分析。您可能会期待自发重置和/或多次数据包重传。 你的代码很可能被严重破坏了。 @Netch ,好的,谢谢您的解释。我是从文档中得到的,但我不确定。这就是我想听到的。我将再次检查我的代码,然后进行数据包捕获。 @Martin James 我会继续查看我的代码。但令人不安的是它在 Windows 上运行得很好......它真的没那么复杂pastebin.com/P1dXRnqB 【参考方案1】:我想通了。我的文件处理代码有 2 个问题。
在上传中:
database_file = drive.CreateFile()
database_file['title'] = packageName
# this needs to be set
database_file.SetContentFile(packageName)
#
database_file['parents']=["kind": "drive#fileLink" ,'id': str(cloudfolderid) ]
在下载时,我使用了错误的 url(webContentLink 仅适用于浏览器,使用 "downloadUrl" )。然后我还需要制作一个标题来授权下载
import urllib2
import json
url = 'https://doc-14-5g-docs.googleusercontent.com/docs/securesc/n4vedqgda15lkaommio7l899vgqu4k84/ugncmscf57d4r6f64b78or1g6b71168t/1409342400000/13487736009921291757/13487736009921291757/0B1umnT9WASfHUHpUaWVkc0xhNzA?h=16653014193614665626&e=download&gd=true'
#Parse saved credentials
credentialsFile = open('./configs/gcreds.dat', 'r')
rawJson = credentialsFile.read()
credentialsFile.close()
values = json.loads(rawJson)
#Header must include: "Authorization" : "Bearer xxxxxxx SomeToken xxxxx"
ConstructedHeader = "Bearer " + str(values["token_response"]["access_token"])
Header = "Authorization": ConstructedHeader
req = urllib2.Request( url, headers= Header )
response = urllib2.urlopen(req)
output = open("UploadTest.z.crypt",'wb')
output.write(response.read())
output.close()
【讨论】:
以上是关于Python Sockets,下载几乎是原始文件大小的 10 倍,上传是 0 字节的主要内容,如果未能解决你的问题,请参考以下文章