Pergunta

Se um servidor e cliente TCP estiverem conectados, gostaria de determinar quando o cliente não está mais conectado. Eu pensei que posso simplesmente fazer isso tentando enviar uma mensagem para o cliente e, uma vez se enviar (), retorna com -1, posso derrubar o soquete. Essa implementação funciona no Windows, mas no minuto em que tento fazer isso no Linux com soquetes BSD, a chamada para enviar () no aplicativo do lado do servidor faz com que o aplicativo do meu servidor trave se o cliente não estiver mais conectado. Nem retorna um -1 ... apenas encerra o programa.

Por favor, explique por que isso está acontecendo. Desde já, obrigado!

Foi útil?

Solução

Isso é causado pelo sinal Sigpipe. Ver send(2):

A função send () deve falhar se:
Epipe] O soquete é desligado para escrever ou o soquete é o modo de conexão e não está mais conectado. No último caso, e se o soquete for do tipo Sock_stream ou Sock_seqpacket e o sinalizador msg_nosignal não será definido, o sinal Sigpipe é gerado para o encadeamento de chamada.

Você pode evitar isso usando o MSG_NOSIGNAL bandeira no send() ligue, ou ignorando o SIGPIPE sinal com signal(SIGPIPE, SIG_IGN) no início do seu programa. Então o send() A função retornará -1 e definirá errno para EPIPE nesta situação.

Outras dicas

Você precisa ignorar o sinal Sigpipe. Se um erro de gravação ocorrer em um soquete, seu processo com o GET SIGPIPE e o comportamento padrão desse sinal é matar seu processo. Escrevendo o código de rede em *nix que você geralmente deseja:

signal(SIGPIPE,SIG_IGN);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top