Как проверить, был ли закрыт сокет на этом конце в Python

У меня есть функция, которая может вызвать socket.close() для разрыва соединения, и я хочу проверить, так ли это. (я про свой скрипт - нет, если бы он был закрыт на другом конце) Почему-то socket._closed все равно возвращает False, а socket._connected возвращает True.

Попытка чтения/записи на него выдает

*** ValueError: Чтение в закрытом или развернутом сокете SSL».

но я хочу проверить без try/except (что довольно грязно). Например.:

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

Есть ли способ сделать это?


person user5908639    schedule 10.02.2016    source источник


Ответы (1)


from Когда не использовать 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()

более простое, компактное решение

Если под «этим концом» вы имели в виду серверную часть, этот ответ должен помочь. Если вы имели в виду клиентскую сторону, следующий код из этого ответа должен работать.

person Valkyrie    schedule 10.02.2016
comment
под этим я подразумеваю сам текущий сценарий. редактирование вопроса с примером... - person user5908639; 10.02.2016
comment
Хорошо, что @Chitoge обрабатывает как клиентские, так и серверные сценарии. Сценарий может запускать либо сервер, либо клиент, либо и то, и другое. Сервер и клиент — более четкие термины, чем сценарий. В Руководстве по программированию сокетов есть несколько важных замечаний относительно отключения. - person OYRM; 10.02.2016
comment
но это не отвечает на мой вопрос... Мой сценарий таков, что я клиент, и я закрываю сокет, и я хочу убедиться, что я это сделал. посмотрите на пример, который я дал в вопросе. - person user5908639; 11.02.2016