Pergunta

Recentemente, vi um pouco de código que olhou como este (com meia sendo um objeto de soquete é claro):

sock.shutdown(socket.SHUT_RDWR)
sock.close()

O que é exatamente o propósito de chamar shutdown na tomada e, em seguida, fechá-lo? Se ele faz a diferença, esta tomada está sendo usado para não-bloqueio IO.

Foi útil?

Solução

Aqui está um explicação :

Uma vez que um socket não é mais necessária, o programa de chamada pode descartar a Tomada pela aplicação de uma sub-rotina perto para o descritor de socket. Se um soquete entrega fiável tem dados associada a ele quando uma estreita leva lugar, o sistema continua a tentar transferência de dados. No entanto, se os dados forem ainda não entregues, as devoluções do sistema os dados. Caso o pedido programa não tem nenhum uso para qualquer pendente dados, ele pode usar o desligamento sub-rotina sobre a tomada prévia fechá-lo.

Outras dicas

Chamando close e shutdown ter dois efeitos diferentes sobre o soquete subjacente.

A primeira coisa a salientar é que o soquete é um recurso no sistema operacional subjacente e vários processos podem ter uma alça para o mesmo soquete subjacente.

Quando você chama close que diminui o número de identificador por um e se a contagem de identificador atingiu zero, então o soquete e conexão associados tramita perto normal (envio efetivamente um FIN / EOF para o peer) eo soquete é desalocada .

A única coisa a prestar atenção aqui é que se a contagem de identificador não chegar a zero porque outro processo ainda tem um identificador para o soquete em seguida, a conexão não está fechada e o socket não é desalocada.

Por outro lado chamando shutdown para a leitura e escrita fecha a conexão subjacente e envia um FIN / EOF para o peer independentemente de quantos processos têm identificadores para o socket. No entanto, ele não desalocar o soquete e você ainda precisa chamar perto depois.

Explicação de desligamento e perto: desligamento (MSDN)

Shutdown (no seu caso) indica para a outra extremidade da conexão não há mais intenção de ler ou escrever para o socket. liberta em seguida, feche até qualquer memória associada com o soquete.

Omitting desligamento pode fazer com que o casquilho a ficar na pilha SOs até que a ligação tenha sido fechado normalmente.

IMO os nomes 'desligamento' e 'fechar' são enganosas, 'close' e 'destruir' seria enfatizar suas diferenças.

é mencionado mesmo no COMO FAZER Programação Socket ( PY2 / < a href = "http://docs.python.org/3/howto/sockets.html#disconnecting" rel = "noreferrer"> PY3 )

Desligar

Estritamente falando, você deveria usar shutdown em um soquete antes de close-lo. O shutdown é um aviso à tomada na outra extremidade. Dependendo do argumento que você passá-lo, pode significar “ Eu não estou indo para enviar mais, mas eu ainda vou ouvir ”, ou “ Eu não estou escutando, boa viagem! ”. A maioria das bibliotecas de soquete, no entanto, estão tão acostumados a programadores deixar de usar este pedaço de etiqueta que normalmente um close é o mesmo que shutdown(); close(). Assim, na maioria das situações, não é necessário um desligamento explícito.

...

Não é este código acima errado?

A triz diretamente após a chamada de desligamento pode fazer o kernel descartar todos os buffers de saída de qualquer maneira.

De acordo com http://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable é preciso esperar entre o desligamento ea estreita até a volta de leitura 0.

existem alguns sabores de desligamento: http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.shutdown.aspx . * Nix é semelhante.

Shutdown (1), as forças da tomada nenhuma para enviar mais dados

Isso é útil em

1- Esvaziando buffer

2- erro estranho detecção

3 guarda de segurança

Deixe-me explicar mais, quando você enviar um conjunto de dados de A para B, não é garantido para ser enviado para B, só é garantido para ser enviado para o buffer de um sistema operacional, que por sua vez envia para o B OS tampão

Assim, chamando shutdown (1) em A, você tampão flush de A e será gerado um erro Se a memória intermédia não está vazia ou seja: dados não tiver sido enviado para o ponto ainda

Howoever este é irrevesable, para que possa fazer isso depois que você completamente enviou todos os seus dados e você quer ter certeza de que é pelo menos no par OS tampão

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top