Python - 如何检查套接字是否仍然连接

时间:2017-12-29 15:21:26

标签: python sockets networking tcp tcpclient

我有以下代码,这是自我解释的:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(host, port)
s.send("some data")
# don't close socket just yet... 
# do some other stuff with the data (normal string operations)
if s.stillconnected() is true:
    s.send("some more data")
if s.stillconnected() is false:
    # recreate the socket and reconnect
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(host, port)
    s.send("some more data")
s.close()

如何实施s.stillconnected() 我不想盲目地重新创造插座。

2 个答案:

答案 0 :(得分:4)

如果服务器连接不再存在,则调用send方法将引发异常,因此您可以使用try-exception块尝试发送数据,捕获异常(如果它被抛出)并重新建立连接:

try:
    s.send("some more data")
except:
    # recreate the socket and reconnect
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(host, port)
    s.send("some more data")

编辑:根据@ Jean-Paul Calderone的评论,请考虑使用sendall方法,这是一种更高级别的方法,可以发送所有数据或引发错误,而不是send,这是一个不保证传输所有数据的低级方法,或者使用更高级别的模块,如可以处理套接字生命周期的HTTP库。

答案 1 :(得分:2)

使用此变体检查套接字是否关闭(如果要检查它是否仍处于连接状态,则结果否定),我取得了良好的结果:

import logging
import socket


logger = logging.getLogger(__name__)


def is_socket_closed(sock: socket.socket) -> bool:
    try:
        # this will try to read bytes without blocking and also without removing them from buffer (peek only)
        data = sock.recv(16, socket.MSG_DONTWAIT | socket.MSG_PEEK)
        if len(data) == 0:
            return True
    except BlockingIOError:
        return False  # socket is open and reading from it would block
    except ConnectionResetError:
        return True  # socket was closed for some other reason
    except Exception as e:
        logger.exception("unexpected exception when checking if a socket is closed")
        return False
    return False