Pergunta

Iam tentando criar um servidor iterativo baseado em datagrama soquetes (UDP). Ele chama de conexão para o primeiro cliente que recebe da primeira chamada recvfrom () (sim, eu sei que isso não é verdadeira conexão). Depois de ter servido este cliente, eu desligar o soquete UDP (chamando conexão com AF_UNSPEC) Então eu recvfrom chamada () para obter o primeiro pacote a partir do próximo cliente.

Agora, o problema é, que a chamada de recvfrom () na segunda iteração do loop está retornando 0. Meu clientes nunca enviar pacotes vazios, então o que poderia estar acontecendo.

Isto é o que Iam fazer (pseudocódigo):

s = socket(PF_INET, SOCK_DGRAM, 0)

bind(s)

for(;;)
{
  recvfrom(s, header, &client_address)  // get first packet from client
  connect(s,client_address)  // connect to this client
  serve_client(s);
  connect(s, AF_UNSPEC); // disconnect, ready to serve next client
}

EDIT: Eu encontrei o bug no meu cliente acidentalmente enviar um pacote vazio. Agora o meu problema é como fazer com que o tempo de espera do cliente para obter servido em vez de enviar um pedido para o nada (servidor está conectado a outro cliente e não serve qualquer outro cliente ainda).

Foi útil?

Solução

connect () é realmente completamente desnecessário em SOCK_DGRAM.

Chamando connect não impedi-lo de receber pacotes de outros hosts , nem impedi-lo de enviá-los. Só não se preocupar, não é realmente útil.

CORREÇÃO: sim, aparentemente, o impede de receber pacotes de outros hosts. Mas fazer isso em um servidor é um bocado parvo porque quaisquer outros clientes seria bloqueado enquanto você estava connect () ed para um. Além disso, você ainda precisa pegar "joio", que flutuam. Há provavelmente algumas condições de corrida associados com connect () em uma tomada dgram - o que acontece se você chamar connect e pacotes de outros hosts já estão no buffer

?

Além disso, 0 é um valor de retorno válido a partir recvfrom (), como (sem dados) pacotes vazios são válidos e podem existir (na verdade, as pessoas muitas vezes usá-los). Então você não pode verificar se algo foi bem sucedido dessa forma.

Em toda a probabilidade, um pacote byte zero estava na fila já.

O protocolo deve ser projetada para minimizar a chance de um datagrama errante ser mal interpretado; por esta razão eu sugiro que você não usa datagramas vazias, e usar um número mágico em seu lugar.

aplicações UDP deve ser capaz de reconhecer pacotes "joio" e soltando-os; eles vão virar-se mais cedo ou mais tarde.

Outras dicas

man connect:

...
If the initiating socket is not connection-mode, then connect()
shall set the socket’s peer address, and no connection is made.
For SOCK_DGRAM sockets, the peer address identifies where all
datagrams are sent on subsequent send() functions, and limits
the remote sender for subsequent recv() functions. If address
is a null address for the protocol,  the  socket’s  peer  address
shall be reset.
...

Apenas uma correção em ninguém stumbples caso através deste como eu fiz. Para desconectar connect () precisa ser chamado com o membro sa_family de sockaddr conjunto para AF_UNSPEC. Não apenas passou AF_UNSPEC.

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