zoukankan      html  css  js  c++  java
  • 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在背景中一个单独的线程。
  • 相关阅读:
    Android最佳性能实践(二)——分析内存的使用情况
    Android最佳性能实践(一)——合理管理内存
    Java反射机制
    Java基础知识总结之IO流
    Java之IO流详解
    CentOS 6.4安装中文支持
    because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'style-src' was not explicitly set, so 'default-src' is used as a fallback.错误应该怎么解决?
    在asp.net添加引用Microsoft.VisualBasic全过程
    SQL SERVER 2012安装介质
    Microsoft SQL Server附加数据库错误:5123
  • 原文地址:https://www.cnblogs.com/ferraborghini/p/4976279.html
Copyright © 2011-2022 走看看