Pagina 1 di 1
[C] recv() non bloccante
Inviato: sab 10 nov 2007, 3:53
da Dani
In un programma (client) mi aspetto di ricevere da un server qualcosa tipo:
non conosco il numero di stringhe che saranno inviate, e dopo aver ricevuto l'ultima mi si blocca il programma. In pratica recv() continua ad aspettare altri dati, solo che non arriveranno mai

E' possibile mettere un timeout alla funzione ?
Inviato: sab 10 nov 2007, 12:55
da gallows
man 3 poll
Se hai qualche dubbio su come funziona ti faccio un esempio.
Inviato: sab 10 nov 2007, 13:58
da mcosta
Le soluzioni sono 2:
1) Usi la select() a cui puoi impostare un timeout e poi usi recv() per scodare dal buffer
2) Imposti il socket in modalità non bloccante e controlli il risultato della recv() per accorgerti che non c'è nulla da leggere
Inviato: sab 10 nov 2007, 16:31
da Dani
Avevo trovato qualcosa sulla select() ma non capisco perchè il programma subito dopo il timeout va in segfault:
Codice: Seleziona tutto
...
FD_ZERO (&read_set);
while (1)
{
FD_SET (sd, &read_set);
timeout.tv_sec = 5;
timeout.tv_usec = 0;
rval = select (sd + 1, &read_set, NULL, NULL, &timeout);
if (rval < 0)
_error ("select() call failed."); /* uscita dal programma */
else if (rval)
{
if ((read = recv (sd, buff, size, 0)) < 0)
_error ("..."); /* uscita dal programma */
buff[read] = 0;
... /* qui altro codice per estrarre cio' che mi serve dai dati ricevuti */
}
else
{
printf ("\nTimeout occured.\n");
break;
}
}
return 0;
Appena il programma arriva al return va in segfault...
Inviato: sab 10 nov 2007, 17:16
da gallows
Sicuro che non ottiene un SIGSEGV quando manipoli il buffer? Per analizzare ciò che avviene prova strace o meglio ancora gdb. Oppure allega (o linka se è lungo) l'intero programma e gli diamo un'occhiata.
EDIT: ad ogni modo, sembra che tu debba controllare un solo file descriptor, in questo caso, IMO, è più logico usare poll...
Inviato: sab 10 nov 2007, 20:05
da Dani
Si infatti, avevo fatto un po' di casino con i puntatori

Ho continuato ad usare la select() perchè ho trovato poca documentazione riguardo la poll()...Certo che queste funzioni sono alquanto criptiche (o sono io negato ?)

Inviato: sab 10 nov 2007, 22:15
da gallows
Guarda, poll è abbastanza semplice:
Codice: Seleziona tutto
/* ... */
#include <poll.h>
TcpData* tcp_recv(int fd)
{
/* ... */
struct pollfd pfd; /* struttura per UN fd da monitorare */
pfd.fd = fd; /* assegno il file descriptor del socket */
pfd.events = POLLIN; /* mi aspetto eventi in entrata */
for (;;) {
/* primo argomento: puntatore alle strutture da monitorare, in questo caso è una sola
* secondo: numero di strutture
* terzo: timeout in msec
*/
int res = poll(&pfd, 1, TIMEOUT);
if (!res) {
/* time out */
}
else if (res < 0) {
/* errore */
}
else {
/* lettura del socket */
}
}
return data;
}
Inviato: lun 12 nov 2007, 18:38
da Dani
Capito, grazie mille !