python多線程發送socket數據,主線程保持接收狀態,settimeout()的相關用法


轉載:http://codego.net/9140379/

有點亂后期在做整理

1.在非阻塞套接字沒有數據可用的情況下,recv的會拋出異常socket.error和異常的價值將要么EAGAIN或者EWOULDBLOCK的錯誤號。例如:

import sys
import socket
import fcntl, os
import errno
from time import sleep
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1',9999))
fcntl.fcntl(s, fcntl.F_SETFL, os.O_NONBLOCK)
while True:
 try:
  msg = s.recv(4096)
 except socket.error, e:
  err = e.args[0]
  if err == errno.EAGAIN or err == errno.EWOULDBLOCK:
   sleep(1)
   print 'No data available'
   continue
  else:
   # a "real" error occurred
   print e
   sys.exit(1)
 else:
  # got a message, do something :)

這種情況在該情況下,有一點不同,你已經通過了出去啟用非阻塞行為s.settimeout(n)。在這種情況下,socket.error是史迪威提出,但在一列的情況下,異常的值始終設置為“出”的字符串。因此 CodeGo.net,要處理這種情況,你可以這樣做:

import sys
import socket
from time import sleep
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1',9999))
s.settimeout(2)
while True:
 try:
  msg = s.recv(4096)
 except socket.timeout, e:
  err = e.args[0]
  # this next if/else is a bit redundant, but illustrates how the
  # timeout exception is setup
  if err == 'timed out':
   sleep(1)
   print 'recv timed out, retry later'
   continue
  else:
   print e
   sys.exit(1)
 except socket.error, e:
  # Something else happened, handle error, exit, etc.
  print e
  sys.exit(1)
 else:
  if len(msg) == 0:
   print 'orderly shutdown on server end'
   sys.exit(0)
  else:
   # got a message do something :)

如指出的,這也是一種更輕便的解決方案,因為它不依賴於OS的特定函數,以將sockets插入非blockng模式。
 請參閱recv(2)和Python接口的更多細節。

2. 這很簡單:如果recv()您將不會收到這方面的任何更多的數據。永遠。您可能仍然能夠發送。 您的非阻塞套接字必須拋出一個異常(可能是依賴於系統的)如果沒有可用數據,但連接仍然活着(另一端可以發送)。
3. 當recv在連接select如果套接字准備好被讀取,但沒有數據讀取客戶端端已經關閉了連接。 這里是處理這段代碼,還要注意,當拋出異常recv被稱為第二個while循環。如果沒有什么留下來讀這將引發異常沒有關系“客戶端端已經關閉了連接:
def listenToSockets(self):
 while True:
  changed_sockets = self.currentSockets
  ready_to_read, ready_to_write, in_error = select.select(changed_sockets, [], [], 0.1)
  for s in ready_to_read:
   if s == self.serverSocket:
    self.acceptNewConnection(s)
   else:
    self.readDataFromSocket(s)
和接收數據的函數:
def readDataFromSocket(self, socket):
 data = ''
 buffer = ''
 try:
  while True:
   data = socket.recv(4096)
   if not data: 
    break
   buffer += data
 except error, (errorCode,message): 
  # error 10035 is no data available, it is non-fatal
  if errorCode != 10035:
   print 'socket.error - ('+str(errorCode)+') ' + message

 if data:
  print 'received '+ buffer
 else:
  print 'disconnected'

只是現有的答案,我會選擇,而不是非阻塞套接字。問題是,非阻塞的東西(也許除了發送),所以我會說,沒有理由他們。如果你經常有你的應用程序被阻塞,等待IO的問題,我也會考慮做IO在背景中一個單獨的線程。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM