PDA

Visualizza la versione completa : [C] Problema creazione socket


Smoke666
15-10-2012, 11:31
Ciao a tutti, sono in fase di test del mio progetto e ho trovato un errore veramente strano. Facendo il debug mi sono accorto che la funzione che crea una socket fallisce sempre. In particolare le chiamate a bind() e listen() restituiscono sempre -1, nonostante tutti gli argomenti siano corretti! Vi incollo un po di codice:



int creaSock(char* path){
struct sockaddr_un sad;
int mySocket, len;
//controlli sul path tutti corretti.
mySocket = socket(AF_UNIX, SOCK_STREAM, 0);

if(mySocket < 0) return -1;

sad.sun_family = AF_UNIX;
strncpy(sad.sun_path, path, strlen(path));
len = sizeof(sad);
//tutte e due le funzioni falliscono, ho provato a dividere questo if mettendo prima la listen e poi bind, //stesso risultato
if ( (bind(mySocket, (struct sockaddr *)&sad, len) < 0) || (listen(mySocket, SOMAXCONN))<0){
return -1;
}

return mySocket;
}



Spero possiate darmi una mano! Vi ringrazio!

oregon
16-10-2012, 11:19
Con cosa lavori? Compilatore? Sistema operativo?

Smoke666
16-10-2012, 11:24
Sto lavorando sotto Ubuntu 12.04 e compilo con gcc.
Faccio un piccolo aggiornamento del problema: includendo nel codice perror() relativo alla bind, ottengo come risultato "No such file or directory". Siccome i test cercano di creare diverse socket sbagliate prima di creare quella corretta, ho pensato che ci fosse un problema con la struttura sockaddr_un, così ho inserito un


memset(&sad,0, sizeof (struct sockaddr_un));

prima di assegnare nuovamente l'indirizzo, per "azzerare" eventuali modifiche ogni qual volta la funzione viene richiamata ma l'errore rimane...

c0der
16-10-2012, 11:41
Il "No such file or directory" mi fa pensare che la path non sia esatta, cioé che non esista una delle directory che la costituiscono, non tanto il socket file (dello unix socket), perché quello viene creato se non esiste (mentre se esistesse già ti darebbe "Address already in use").

Smoke666
16-10-2012, 11:47
Ci stavo pensando anche io. In effetti il path mi è stato fornito insieme ai test (si tratta di un progetto universitario), non vorrei che non esistesse sulla mia macchina! Ora provo a crearlo manualmente e vi aggiorno!


Edit: Anche creando il path manualmente resta tutto inalterato.

c0der
16-10-2012, 12:01
Ho ridotto un po' la tua funzione, prova così solo per capire se almeno questo ti funziona...



#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

int main()
{
struct sockaddr_un sad;
int mySocket;

mySocket = socket(AF_UNIX, SOCK_STREAM, 0);
if (mySocket < 0)
return 1;

memset(&sad,0, sizeof (struct sockaddr_un));
sad.sun_family = AF_UNIX;
strcpy(sad.sun_path, "/tmp/miosocket");
if (bind(mySocket, (struct sockaddr *) &sad, sizeof(sad)) < 0) {
perror("errore bind");
return 1;
} else
printf("bind ok\n");


return 0;
}

Smoke666
16-10-2012, 12:04
Si questo funziona, e funziona anche la listen sullo stesso path.

c0der
16-10-2012, 12:23
Bene, allora sostituisci "/tmp/miosocket" con il path reale e vedi cosa succede.

Smoke666
16-10-2012, 12:25
Dunque ho sostituito e funziona. Questa sarà una soluzione temporanea però, non credo di poter modificare il file dei test scritto dalla prof. Andrò a provarlo anche sulle macchine del laboratorio e vediamo cosa succede. Un'altra cosa, ora la successiva chiamata ad accept() si blocca senza errori. Semplicemente si inchioda li e non va oltre. Siccome è una funzione separata alla quale posso passare solo il file descriptor della socket, la chiamo così:


accept(socket, NULL, NULL);

E' corretto?

Who am I
16-10-2012, 13:05
Originariamente inviato da Smoke666
Dunque ho sostituito e funziona. Questa sarà una soluzione temporanea però, non credo di poter modificare il file dei test scritto dalla prof. Andrò a provarlo anche sulle macchine del laboratorio e vediamo cosa succede. Un'altra cosa, ora la successiva chiamata ad accept() si blocca senza errori. Semplicemente si inchioda li e non va oltre. Siccome è una funzione separata alla quale posso passare solo il file descriptor della socket, la chiamo così:


accept(socket, NULL, NULL);

E' corretto?

La accept è bloccante, per cui finché non c'è un altro processo che si connette al socket il codice si ferma in attesa.

Loading