差異處

這裏顯示兩個版本的差異處。

連向這個比對檢視

Both sides previous revision 前次修改
下次修改
前次修改
python:socket:send_resource_temporarilty_unvailable_error [2016/09/12 15:15]
tony
python:socket:send_resource_temporarilty_unvailable_error [2023/06/25 09:48] (目前版本)
行 51: 行 51:
 [Errno 11] Resource temporarilty unavaliable [Errno 11] Resource temporarilty unavaliable
 </​code>​ </​code>​
-===== 實驗 ​=====+===== Diagnosis ​=====
 ==== 實驗1 - 分批送+sleep ==== ==== 實驗1 - 分批送+sleep ====
 首先我發現接收到的檔案大小一定是33304 bytes,於是我加了以下程式做試驗:​ 首先我發現接收到的檔案大小一定是33304 bytes,於是我加了以下程式做試驗:​
行 83: 行 83:
 </​code>​ </​code>​
 我猜測透過strace可能也造成send資料之間的延遲,好讓buffer有足夠時間釋放。 我猜測透過strace可能也造成send資料之間的延遲,好讓buffer有足夠時間釋放。
 +===== How to resolve? =====
 +根據實驗結果,有以下結論:​
 +  - 實驗二說明在blocking mode下,sendall應能正常傳送資料。實驗三為例外,原因還不明。
 +  - 實驗一與四說明,如果將send分批進行且有緩衝,應能正常傳送資料。
 +  - 並非所有OS有相同結果,可能與python或內核有關。
 +綜合以上,如果要設定timeout,安全作法應該使用non-blocking IO的存取方式。因此參考[[https://​vaidik.in/​blog/​understanding-non-blocking-io-with-python-part-1.html|此篇文章]]修改程式碼,針對Resource temporarilty unavaliable錯誤retry:​
 +<code python>
 +def sendData(sock,​ data):
 + total_sent = 0
 + while len(data):
 + try:
 + sent = sock.send(data)
 + total_sent += sent
 + data = data[sent:]
 + print '​Sending data'
 + except socket.error,​ e:
 + if e.errno != errno.EAGAIN:​
 + raise e
 + print '​Blocking with', len(data), '​remaining'​
 + select.select([],​ [sock], [])  ​
 + return total_sent
 +</​code>​
 +呼叫程式改為:​
 +<code python>
 +data = debugfile.read()
 +total_data = len(data)
 +total_send = sendData(conn,​ data)
 +print "data size = %s, send size = %s" % (total_data,​ total_send)
 +</​code>​
 ===== Reference ===== ===== Reference =====
   * [[https://​fwengineer.blogspot.tw/​2013/​05/​setsockopt.html|setsockopt]]   * [[https://​fwengineer.blogspot.tw/​2013/​05/​setsockopt.html|setsockopt]]