【问题标题】:Python Tcp disconnect detectionPython Tcp断开检测
【发布时间】:2014-01-09 18:11:53
【问题描述】:

我有一个 simpletcp 示例:

import socket
import time


TCP_IP = '127.0.0.1'
TCP_PORT = 81
BUFFER_SIZE = 1024

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))

while True:
    s.send(bytes('hello', 'UTF-8'))
    time.sleep(1)

s.close()

如果我失去了与服务器的连接,我该如何检测,然后如何安全地重新连接?

是否需要等待服务器回复?

更新:

import socket
import time

TCP_IP = '127.0.0.1'
TCP_PORT = 81
BUFFER_SIZE = 1024

def reconnect():
    toBreak = False
    while True:
        s.close()
        try:
            s.connect((TCP_IP, TCP_PORT))
            toBreak = True
        except:
            print ("except")        
        if toBreak:
            break
        time.sleep(1)


s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))

while True:
    try:    
        s.send(bytes('hello', 'UTF-8'))
        print ("sent hello")
    except socket.error as e:
        reconnect()

    time.sleep(1)

s.close()

如果我断开连接,它会引发错误(并不重要),然后转到 重新连接循环。但是在我恢复连接后,连接会返回此错误:

OSError: [WinError 10038] 尝试对非套接字的操作进行操作

如果我重新启动调用相同 s.connect((TCP_IP, TCP_PORT)) 的脚本,它可以正常工作。

【问题讨论】:

    标签: python tcp


    【解决方案1】:

    如果连接丢失或断开,您将在任何对send()recv() 的调用中收到socket.error:[Errno 104] Connection reset by peer 异常(又名ECONNRESET)。因此,要检测到这一点,只需捕获该异常:

    while True:
        try:
            s.send(bytes('hello', 'UTF-8'))
        except socket.error, e:
            if e.errno == errno.ECONNRESET:
                # Handle disconnection -- close & reopen socket etc.
            else:
                # Other error, re-raise
                raise
        time.sleep(1)
    

    【讨论】:

    • 你的意思是:除了 socket.error as e: 吗?如果我终止连接,它会引发以下错误:ECONNABORTED,但重新连接不起作用。
    • @AndrásKovács:as, 都是将异常对象存储到目标变量 docs.python.org/2/reference/compound_stmts.html#except 的相同语法。如果您看到的是ECONNABORTED 而不是ECONNRESET,那么也要测试该值并适当地处理它。一旦套接字达到错误状态,您就不能重用该套接字。您必须关闭套接字并打开一个新的。
    • 更新了帖子。看来,简单的重新连接并不能解决问题。
    • 或者,可以使用except ConnectionResetError:
    【解决方案2】:

    尝试重新连接时使用新的套接字。

    def connect():
        while True:
            try:
                s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                s.connect((host, port))
                return s.makefile('w')
            except socket.error as e:
                log("socket error {} reconnecting".format(e))
                time.sleep(5)
    
    dest = connect()
    while True:
        line = p.stdout.readline()
        try:
            dest.write(line)
            dest.flush()
        except socket.error as e:
            log("socket error {} reconnecting".format(e))
            dest = connect()
    

    【讨论】:

      【解决方案3】:

      你能试试吗(我认为你没有尝试socket.SO_REUSEADDR):

      def open_connection():
          data0=''
      
          try:
              # Create a TCP/IP socket
              sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
              sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
      
              # Connect the socket to the port where the server is listening
              server_address = ('192.168.0.100', 8000)
              sock.settimeout(10)     # TimeOut 5 secunde
      
              while True:
      
                  try:
                      sock.connect(server_address)
                      message = 'new connection'
                      sock.sendall(message)
      
                      # Look for the response
                      amount_received = 0
                      data0=sock.recv(1024)
                      amount_received = len(data0)
                      return
      
                  finally:
                      wNET = 0
                      pass
      
          except:
              sock.close()
              time.sleep(60)
              del data0
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-02-10
        • 1970-01-01
        • 2014-01-24
        • 2020-07-04
        • 1970-01-01
        • 2013-06-23
        • 2019-04-27
        • 2013-11-16
        相关资源
        最近更新 更多