Domanda

Iam cercando di creare un server iterativo basato su socket datagram (UDP). Chiede connettersi al primo cliente, che si ottiene dalla chiamata prima recvfrom () (sì, lo so questo non è un vero e proprio collegamento). Dopo aver servito questo client, stacco il socket UDP (chiamando connettersi con AF_UNSPEC) Poi chiamo recvfrom () per ottenere il primo pacchetto dal prossimo cliente.

Ora il problema è, che la chiamata di recvfrom () nella seconda iterazione del ciclo sta tornando 0. I miei clienti non inviare i pacchetti vuoti, quindi quello che potrebbe essere in corso.

Questo è ciò che Iam facendo (pseudocodice):

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: Ho trovato il bug nel mio client di inviare accidentalmente un pacchetto vuoto. Ora il mio problema è come rendere il cliente attesa per ottenere invece serviti di inviare una richiesta nel nulla (server è collegato ad un altro cliente e non serve qualsiasi altro client ancora).

È stato utile?

Soluzione

connect () è in realtà completamente inutile su SOCK_DGRAM.

La chiamata collegare non si ferma si riceve pacchetti da altri host , né si fermano inviando loro. Basta non preoccupatevi, non è davvero utile.

CORREZIONE: sì, a quanto pare si ferma si ricezione di pacchetti da altri host. Ma fare questo in un server è un po 'sciocco, perché tutti gli altri clienti sarebbero stati bloccati mentre eri connect () ed a uno. Inoltre avrai ancora bisogno di recuperare "pula", che galleggiano intorno. Probabilmente ci sono alcune condizioni di gara connessi con connect () su un socket dgram -? Che cosa succede se si chiama connettersi e pacchetti provenienti da altri host già nel buffer

Inoltre, 0 è un valore restituito valido da recvfrom (), come vuoti (nessun dato) pacchetti sono validi e possono esistere (anzi, le persone spesso li usano). Così non si può verificare se qualcosa è riuscita in questo modo.

In ogni probabilità, un pacchetto di zero byte era già coda.

Il protocollo deve essere progettato per ridurre al minimo la possibilità di un datagramma errante essere frainteso; per questo motivo mi suggeriscono di non usare datagrammi vuote, e utilizzare un numero magico posto.

UDP applicazioni devono essere in grado di riconoscere i pacchetti "pula" e rilasciandoli; si rivolgeranno prima o poi.

Altri suggerimenti

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.
...

solo una correzione nel caso qualcuno stumbples in questo come ho fatto io. Per scollegare connect () deve essere chiamato con l'organo di sa_family sockaddr impostato AF_UNSPEC. Non appena superato AF_UNSPEC.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top