【问题标题】:Boto file upload to S3 failing on Windows [errno: 10054]在 Windows 上将 Boto 文件上传到 S3 失败 [errno: 10054]
【发布时间】:2014-07-01 22:53:59
【问题描述】:

我正在尝试在 Windows 7 机器上使用 boto 将文件上传到 S3,但我不断收到错误消息 [Errno 10054] An existing connection was forcibly closed by the remote host

我与 S3 交互的代码如下所示

from boto.s3.connection import S3Connection
from boto.s3.key import Key

conn = S3Connection(Access_Key_ID, Secret_Key)
bucket = conn.lookup(bucket_name)

k = Key(bucket)
k.key = 'akeynameformyfile'
k.set_contents_from_filename(source_path_of_file_to_upload)

使用 AWS CLI 和以下命令在同一台机器上上传工作正常

aws s3 cp filename.exe s3://bucketname/ttt

文件大约200MB

我的操作系统是 Windows 7,python 通过 anaconda 运行,所有软件包都是最新的。 Boto 是 2.25 版

这段代码在同一网络上的 CentOS 机器上运行良好。那么这是 Windows 的问题吗?

任何帮助将不胜感激 谢谢! c

下面的调试输出

发送:'HEAD / HTTP/1.1\r\n主机: ACCESS_KEY_ID.test7.s3.amazonaws.com\r\n接受编码: 身份\r\n日期:2014 年 5 月 14 日,星期三 22:44:31 GMT\r\n内容长度: 0\r\n授权:AWS ACCESS_KEY_ID:SOME_STUFF=\r\n用户代理: 博托/2.25。 0 Python/2.7.5 Windows/7\r\n\r\n'
回复:'HTTP/1.1 307 临时重定向\r\n'
标头:x-amz-request-id:8A3D34FB0E0FD8E4
标头:x-amz-id-2: PwG9yzOVwxy21LmcpQ0jAaMchG0baCrfEhAU9fstlPUI307Qxth32uNAOVv72B2L
标题: 位置: https://ACCESS_KEY_ID.test7.s3-ap-southeast-2.amazonaws.com/
标头:内容类型:应用程序/xml
标头:传输编码:分块
标题:日期:格林威治标准时间 2014 年 5 月 14 日星期三 22:44:31
标头:服务器:AmazonS3
发送:'HEAD / HTTP/1.1\r\n主机: ACCESS_KEY_ID.test7.s3-ap-southeast-2.amazonaws.com\r\n接受编码: 身份\r\n日期:我们 d,2014 年 5 月 14 日 22:44:31 GMT\r\n内容长度: 0\r\n授权:AWS ACCESS_KEY_ID:SOME_STUFF=\r\n用户代理: Boto/2.25.0 Python/2.7.5 Windows/7\r\n\r\n'
回复:'HTTP/1.1 200 OK\r\n'
标头:x-amz-id-2: 时代RIpbOrEwOU72VUAqU9AGJ4/kX5z1/UD7rJQy9laKDgOyTyVKABMab8f6wGN
标头:x-amz-request-id:2A7BECC45C9BAE7A
标题:日期:格林威治标准时间 2014 年 5 月 14 日星期三 22:44:33
标头:内容类型:应用程序/xml
标头:传输编码:分块
标头:服务器:AmazonS3
发送:'PUT /akeynameformyfile HTTP/1.1\r\n主机: ACCESS_KEY_ID.test7.s3.amazonaws.com\r\n接受编码: 身份\r\n内容 -长度:242642944\r\n内容-MD5:xYOiNcyFKGY1Y/HsYwHQeg==\r\n预期:100-继续\r\n日期:2014 年 5 月 14 日星期三 22:44:33 GMT\r\n用户代理: Boto/2.25.0 Python/2.7.5 Windows/7\r\n内容类型: 应用程序/八位字节流\r\n授权:AWS ACCESS_KEY_ID:pWs3KwRv9Q5wDnz4dHD3JwvCy/w=\r\n\r\n'

----------------------------------- ---------------------------- 错误回溯(最近的调用 最后)
在 ()

 12 k = Key(bucket)                                                                                                            
 13 k.key = 'akeynameformyfile'                                                                                                

---> 14 k.set_contents_from_filename(full_path_of_file_to_upload)
C:\Users\username\AppData\Local\Continuum\Anaconda\lib\site-packages\boto\s3\key.pyc 在 set_contents_from_filename(sel f, 文件名, 标题, 替换, cb, num_cb、策略、md5、reduce_redundancy、encrypt_key)
第1313章 md5, 1314
减少冗余,

-> 1315 encrypt_key=encrypt_key)
1316
第1317章 替换=真,
C:\Users\username\AppData\Local\Continuum\Anaconda\lib\site-packages\boto\s3\key.pyc 在 set_contents_from_file(self, f p, headers, replace, cb, num_cb, 策略、md5、reduce_redundancy、query_args、encrypt_key、大小、 倒带)1244
self.send_file(fp, headers=headers, cb=cb, num_cb=num_cb,
第1245章

-> 1246 chunked_transfer=chunked_transfer, size=size) 1247

返回写入的字节数。第1248章
                                                                                                                                C:\Users\username\AppData\Local\Continuum\Anaconda\lib\site-packages\boto\s3\key.pyc

在 send_file(self, fp, headers, c b, num_cb, query_args, chunked_transfer,大小)

723         self._send_file_internal(fp, headers=headers, cb=cb, num_cb=num_cb,                                                
724                                  query_args=query_args,                                                                    

--> 725 chunked_transfer=chunked_transfer, size=size)

726                                                                                                                            
727     def _send_file_internal(self, fp, headers=None, cb=None, num_cb=10,                                                    
                                                                                                                                C:\Users\username\AppData\Local\Continuum\Anaconda\lib\site-packages\boto\s3\key.pyc

在 _send_file_internal(self, fp, headers, cb, num_cb, query_args, chunked_transfer, size, hash_algs)

912             headers,                                                                                                       
913             sender=sender,                                                                                                 

--> 914 查询参数=查询参数
915)
第916章 C:\Users\username\AppData\Local\Continuum\Anaconda\lib\site-packages\boto\s3\connection.pyc 在 make_request(self, method, bucket, key, headers, data, query_args, 发件人, override_num_retries, retry_handler)

631             data, host, auth_path, sender,                                                                                 
632             override_num_retries=override_num_retries,                                                                     

--> 633 重试处理程序=重试处理程序
第634章
C:\Users\username\AppData\Local\Continuum\Anaconda\lib\site-packages\boto\connection.pyc 在 make_request(self, method, path, headers, data, host, auth_path, 发件人,override_num_retries,参数,retry_handler)
1028 个参数, 标头、数据、主机)
第1029章 override_num_retries,

-> 1030 重试处理程序=重试处理程序)1031
1032 def 关闭(自我):

                                                                                                                                C:\Users\username\AppData\Local\Continuum\Anaconda\lib\site-packages\boto\connection.pyc

在 _mexe(self, request, sender r, override_num_retries, retry_handler)

905                 if callable(sender):                                                                                       
906                     response = sender(connection, request.method, request.path,                                         

--> 907 request.body, request.headers)

908                 else:                                                                                                      
909                     connection.request(request.method, request.path,                                                       
                                                                                                                                C:\Users\username\AppData\Local\Continuum\Anaconda\lib\site-packages\boto\s3\key.pyc

in sender(http_conn, method, path , data, headers)

813                     http_conn.send('\r\n')                                                                                 
814                 else:                                                                                                      

--> 815 http_conn.send(块)
816 用于蒸煮器中的藻类:
817 消化器[alg].update(chunk)
C:\Users\username\AppData\Local\Continuum\Anaconda\lib\httplib.pyc 在 发送(自我,数据)
803 datablock = data.read(blocksize)
804 其他:
--> 805 self.sock.sendall(数据)
806
第807章 C:\Users\username\AppData\Local\Continuum\Anaconda\lib\ssl.pyc 在 sendall(自我,数据,标志)
227 计数 = 0
228 而(计数 --> 229 v = self.send(data[count:])
230 计数 += v
231退货金额
C:\Users\username\AppData\Local\Continuum\Anaconda\lib\ssl.pyc 在 发送(自我、数据、标志)
第196话:
197 尝试:
--> 198 v = self._sslobj.write(data)
199 除了 SSLError,x:
200 如果 x.args[0] == SSL_ERROR_WANT_READ:
错误:[Errno 10054] 现有连接被强制关闭 远程主机

【问题讨论】:

  • 编辑了原始帖子以包含调试输出。对长度感到抱歉
  • 我注意到您最初收到的是 307 重定向。这可能是因为存储桶位于 ap-southeast-2 区域中,但您正在连接到通用 S3 端点。这应该都可以,但只是为了好玩,您可能想尝试直接连接到ap-southeast-2 S3 端点,看看是否有同样的问题。
  • @garnaat 你是天才!谢谢。我不知道为什么应该/会/确实解决问题,但确实如此。非常感谢!

标签: python amazon-s3 boto


【解决方案1】:

@garnaat 在上面的 cmets 中提出了一个建议,为我解决了这个问题。谢谢!! 出于某种原因,连接到通用端点然后尝试专门上传到ap-southeast-2 S3 端点失败。但是如果我们使用connect_to_region 函数来启动连接并指定我们想要的端点,一切正常!再次感谢,下面是工作示例。

from boto.s3 import connect_to_region
from boto.s3.connection import Location
from boto.s3.key import Key

conn = connect_to_region(Location.APSoutheast2,
                         aws_access_key_id=conf.Access_Key_ID,
                         aws_secret_access_key=conf.Secret_Key)
bucket = conn.lookup(bucket_name) # bucket is located in Location.APSoutheast2

k = Key(bucket)
k.key = 'akeynameformyfile'
k.set_contents_from_filename(source_path_of_file_to_upload)

【讨论】:

  • 我也遇到了同样的问题,ap-southeast-2 区域的存储桶也是如此。很奇怪,因为我可以毫无问题地连接到存储桶并列出文件,但是在尝试上传时,我收到了您上面提到的错误。这也仅在从区域外部连接时才会发生(即,从区域内通过通用 S3 端点连接,然后上传工作正常)。
  • 我一直在尝试连接 connect_s3()。对于小文件,我做 set_contents_from_filename() 没有问题。但是文件稍大一些(~ 300KB)我得到了这个错误。现在一切正常,谢谢!
【解决方案2】:

set_contents_from_filename 接受一个字符串作为 S3 上文件的源。您正在尝试上传现有文件。尝试 set_contents_from_file 指定要上传的现有文件。否则,将文件的内容作为字符串传递给 set_contents_from_filename。

【讨论】:

  • 我认为您可能将set_contents_from_filenameset_contents_from_string 方法混淆了。 set_contents_from_filename 期望文件名作为参数上传。见link
【解决方案3】:

以上所有答案都提供了技术解决方案,但我的第一次体验表明这是一个环境问题。

我的代码与原始问题基本相同。我第一次运行它时没有问题,然后昨晚遇到了同样的错误消息。我找到了这个答案和许多其他答案,但决定因为它(我的代码)第一次运行良好(上传了超过 2 万个文件)我可能在我的机器上或 AWS 是源(和/或可能在某个点)上遇到问题之间)。

我关闭了我的电脑,回家了,当我今天早上重新启动时,原始代码运行良好。

使我得出这个结论的一个观察结果是,在我寻找答案的过程中,我注意到很多关于这个问题的帖子似乎都是在同一时间发生的。这让我想到 AWS 可能有问题。同样,我无法确定它是我的计算机、AWS 服务器还是介于两者之间的某个流量点,但是当我今天早上再次追踪原始代码时,它运行良好。

这是我现在使用的代码(您可以看到与原始问题中的代码非常相似)

import boto
import glob
AWS_KEY = "mykey"
AWS_SECRET = "mySecret"
bucket_name = "myBucket"
numbers = [x for x in range(0,20000,500)]
to_upload = glob.glob('E:\MTurkTablesSelected\\*.htm')

s3 = boto.connect_s3(aws_access_key_id = AWS_KEY, aws_secret_access_key = AWS_SECRET)
bucket = s3.get_bucket(bucket_name)
for n, file_path in enumerate(to_upload):
    upload_key = file_path.split('\\')[-1]
    key = bucket.new_key(upload_key)
    key.set_contents_from_filename(file_path)
    key.set_acl('public-read')
    if n in numbers:
        print n

我现在将超过 10,000 个文件放入一个大型上传中并且没有任何问题。

【讨论】:

    猜你喜欢
    • 2023-01-15
    • 1970-01-01
    • 2017-08-18
    • 2014-06-13
    • 1970-01-01
    • 2012-12-28
    • 2014-12-16
    • 1970-01-01
    • 2012-09-25
    相关资源
    最近更新 更多