PDA

View Full Version : [C] Problema con programmazione socket


alessc
10-09-2006, 18:44
Ciao a tutti,
Ho implementato un sistema di cosimulazione tra due programmi che si parlano via socket. Da un lato ho QEMU, una macchina virtuale tipo VMWARE, dall'altra ho un descrizione di una semplice memoria in SystemC. Per far parlare tra di loro come ho detto utilizzo i socket.
Il problema è che, non sempre, la funzione recv mi dà errore (ritorna -1) e non so dove sbatterci la testa.
C'è un qualche modo (log, altro...) che mi permetta di capire perchè qualche volta la connessione va male?
Uso un sistema operativo linux con kernel aggiornato a 2.6.16

Grazie

Alessandro

ps: ho provato a comunicare con systemC con un altro programmino e funziona alla grande... e i parametri sono gli stessi identici

trallallero
11-09-2006, 11:19
controlla la variabile "errno" ;)

alessc
13-09-2006, 00:50
Grazie per il suggerimento,
Infatti il problema è che errno ritorna EINTR. Da quel poco che sono riuscito a documentarmi è a causa di un segnale che va ad interrompere la recv.

C'è un modo per gestire questo "errore"? cioè fare in modo che questo segnale non vada a rompere le scatole al socket?

Grazie mille!

EDIT: pardon ma l'ora è tarda e i ragionamenti tardano ad arrivare...
Allora... guardando netstat quando la connessione è stabilita all'inizio il risultato è ESTABILISHED, se invece qualcosa va male invece ritrovo CLOSE_WAIT.

Anticipando che io non posso mettere le mani sul "server" se non riavviandolo (quindi non posso gestire il socket direttamente) posso fare qualcosa per riassettare il client?

NA01
13-09-2006, 07:50
controlla la variabile "errno" ;)
o usa perrror, l'output è decisamente di più immediata comprensione :)

ciao!

alessc
13-09-2006, 08:06
Già fatto,
adesso il problema è come gestirlo questo errore... ci ho pensato / cercato tutto ieri e non sono riuscito a trovare niente!

Help! :cry:

ilsensine
13-09-2006, 08:23
EINTR non è un errore; è la segnalazione fatta alle chiamate bloccanti (come recv) che il programma ha ricevuto un segnale. Forse il tuo programma usa segnali, o tu direttamente o indirettamente tramite qualche funzione (ad es. alarm).

La soluzione è semplice: ripetere la syscall esattamente come la hai effettuata.
Ad es:

do {
sz = recv(sock, buf, len, flags);
} while(sz<0 && errno==EINTR);


Nota che quasi tutte le chiamate bloccanti sono interrotte con EINTR in caso di ricezione di segnali.

alessc
13-09-2006, 12:36
Funtiona alla grande!

In verità avevo già provato ma non ho messo la condizione "sz < 1", ho messo solo errno == EINTR.

Grazie mille! :D

ilsensine
14-09-2006, 07:08
non ho messo la condizione "sz < 1"
La condizione è "sz<0".
sz==0 sulla recv indica, sui socket tcp, una condizione di EOF (disconnessione).

alessc
15-09-2006, 00:03
Hai ragione, scusa... ho sbagliato a scrivere... intendevo 0 :cool:

Grazie!