【问题标题】:How to check if a socket was closed on this end in Python如何在Python中检查套接字是否在此端关闭
【发布时间】:2016-02-10 15:30:35
【问题描述】:

我有一个函数可以调用socket.close() 来终止连接,我想检查它是否这样做。 (我说的是我的脚本 - 如果它在另一端关闭,则不是) 出于某种原因,socket._closed 仍然返回 False 和 socket._connected 返回 True。

试图读/写它会抛出

*** ValueError: 读取已关闭或未打包的 SSL 套接字。"

但我想在没有 try/except 的情况下进行验证(这很混乱)。例如:

sock.close()
if sock.is_closed:
    do_something()

有没有办法做到这一点?

【问题讨论】:

    标签: python sockets verify


    【解决方案1】:

    来自When to not just use socket.close()

    def recv_end(the_socket):
        End='SERVER WRONG MARKER'
        total_data=[];data='';got_end=False
        while True:
                data=the_socket.recv(8192)
                if not data: break
                if End in data:
                    total_data.append(data[:data.find(End)])
                    got_end=True
                    break
                total_data.append(data)
                if len(total_data)>1:
                    #check if end_of_data was split
                    last_pair=total_data[-2]+total_data[-1]
                    if End in last_pair:
                        total_data[-2]=last_pair[:last_pair.find(End)]
                        total_data.pop()
                        got_end=True
                        break
        return (got_end,''.join(total_data))
    
    def basic_server(sock):
        got=[]
        got_end,data = recv_end(sock)
        if not got_end:  
            sock.send('ERROR:no end!') #<--- not possible w/close()
        else: sock.sendall(data*2)
        sock.shutdown(1)
        sock.close()
    
    import socket
    Port=4444
    def start_server():
        sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        sock.bind(('',Port))
        sock.listen(5)
        print 'started on',Port
        while True:
            newsock,address=sock.accept()
            basic_server(newsock)
    
    def send_data(data):
        sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        sock.connect(('localhost',Port))
        print 'connected'
        sock.sendall(data+'CLIENT WRONG MARKER')
        print 'sent',data
        sock.shutdown(1)
        print 'shutdown'
        result=[]
        while True:
           got=sock.recv(2)
           if not got: break
           result.append(got)
        sock.close()
        return ''.join(result)
    
    if __name__=='__main__':
        start_server()
    

    更简单、更小的解决方案

    如果您所说的“这一端”是指服务器端,this answer 应该会有所帮助。如果您的意思是客户端,this answer 中的以下代码应该可以工作。

    【讨论】:

    • “这一端”是指当前脚本本身。用一个例子编辑问题...
    • @Chitoge 可以同时处理客户端和服务器场景,这很好。 “脚本”可能正在运行服务器或客户端,或两者兼而有之。服务器和客户端是比脚本更清晰的术语。在,Socket Programming HowTo 有一些重要的注意事项:断开连接。
    • 但这并不能回答我的问题......我的情况是我是客户,我正在关闭套接字,我想验证我是否做到了。看看我在问题中给出的例子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-06
    • 1970-01-01
    相关资源
    最近更新 更多