ホームページ > バックエンド開発 > Python チュートリアル > Pythonソケットタイムアウト設定エラー番号10054

Pythonソケットタイムアウト設定エラー番号10054

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
リリース: 2016-06-16 08:43:32
オリジナル
1629 人が閲覧しました

pythonソケット.エラー: [Errno 10054] リモートホストが既存の接続を強制的に閉じました。問題の解決策:

数日前、Python を使用して Web ページを読みました。 Web サイトでは多数の urlopen 操作が使用されるため、その Web サイトによる攻撃とみなされます。ダウンロードが許可されなくなる場合があります。その結果、request.read() は urlopen() の後にスタックしてしまいました。最後に、errno 10054 がスローされます。

このエラーは、ピアによる接続のリセットです。つまり、伝説的なリモート ホストが接続をリセットしました。原因としては、ソケットのタイムアウトが長すぎることが考えられます。request = urllib.request.urlopen(url); の後に request.close() 操作が実行されなかったり、いくつかのスリープが存在しなかったりする可能性があります。これにより、Web サイトはこの動作が攻撃であると認識します。

具体的な解決策は次のとおりです:

01.import socket 
02.import time 
03.timeout = 20  
04.socket.setdefaulttimeout(timeout)#这里对整个socket层设置超时时间。后续文件中如果再使用到socket,不必再设置  
05.sleep_download_time = 10 
06.time.sleep(sleep_download_time) #这里时间自己设定  
07.request = urllib.request.urlopen(url)#这里是要读取内容的url  
08.content = request.read()#读取,一般会在这里报异常  
09.request.close()#记得要关闭 
ログイン後にコピー

urlopen の後の read() 操作は実際にソケット層の特定の関数を呼び出すためです。したがって、デフォルトのソケット タイムアウトを設定すると、ネットワーク自体が切断される可能性があります。 read()で待つ必要はありません。

もちろん、外側の層を除いて、さらにいくつかの try を記述することもできます。たとえば、

try: 
  time.sleep(self.sleep_download_time) 
  request = urllib.request.urlopen(url) 
  content = request.read() 
  request.close() 
   
except UnicodeDecodeError as e: 
     
  print('-----UnicodeDecodeError url:',url) 
   
except urllib.error.URLError as e: 
  print("-----urlError url:",url) 
 
except socket.timeout as e: 
  print("-----socket timout:",url) 
ログイン後にコピー

一般的には問題ありません。これを言う前に、私は何千もの Web ページのダウンロードをテストしました。ただし、何千ものファイルをダウンロードした場合、私がテストを行ったところ、MS は依然としてこの例外から抜け出します。 time.sleep() の時間が短すぎるか、ネットワークが突然中断された可能性があります。 urllib.request.retrieve() を使用してテストしたところ、データのダウンロードを続けると常に失敗することがわかりました。

簡単な解決策は次のとおりです。まず、私の記事「Python チェックポイントの簡単な実装」を参照してください。まずはチェックポイントを作ります。次に、例外を発生させる上記のコードを while True に変更します。以下の疑似コードを参照してください:

def Download_auto(downloadlist,fun,sleep_time=15): 
  while True:     
    try: # 外包一层try  
      value = fun(downloadlist,sleep_time) # 这里的fun是你的下载函数,我当函数指针传进来。 
      # 只有正常执行方能退出。  
      if value == Util.SUCCESS: 
        break 
    except : # 如果发生了10054或者IOError或者XXXError 
      sleep_time += 5 #多睡5秒,重新执行以上的download.因为做了检查点的缘故,上面的程序会从抛出异常的地方继续执行。防止了因为网络连接不稳定带来的程序中断。 
      print('enlarge sleep time:',sleep_time) 

ログイン後にコピー

ただし、対応する Web ページが見つからない場合は、別のプロセスを実行する必要があります:

# 打印下载信息  
def reporthook(blocks_read, block_size, total_size): 
  if not blocks_read: 
    print ('Connection opened') 
  if total_size < 0: 
    print ('Read %d blocks' % blocks_read) 
  else: 
    # 如果找不到,页面不存在,可能totalsize就是0,不能计算百分比  
    print('downloading:%d MB, totalsize:%d MB' % (blocks_read*block_size/1048576.0,total_size/1048576.0)) 
    
 
def Download(path,url): 
#url = 'http://downloads.sourceforge.net/sourceforge/alliancep2p/Alliance-v1.0.6.jar' 
  #filename = url.rsplit("/")[-1]  
  try: 
  # python自带的下载函数  
    urllib.request.urlretrieve(url, path, reporthook) 
  except IOError as e: # 如果找不到,好像会引发IOError。 
    print("download ",url,"/nerror:",e) 
  print("Done:%s/nCopy to:%s" %(url,path)) 
ログイン後にコピー

それでも問題が発生する場合は、他の解決策をコメントに記入してください。

関連ラベル:
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート