PDA

View Full Version : [C] Problema urgente con i socket


magix2003
24-12-2007, 15:03
Ciao a tutti,
ho un grave problema con i socket. Sto scrivendo la parte "server" del mio programma, ma sto incontrando notevoli difficoltà. Ho questo pezzo di codice che mi danna:


sock_fd = accept(sock_id, NULL, NULL);
if (sock_fd == -1)
die("accept failed");

conn = fdopen(sock_fd, "r+"); // open write read-wrtie stream.

if (conn == NULL)
die("fdopen failed");
fgets(buf, BUFLEN, conn); // read characters from stream.


if (strncmp(buf, "1", 1) == 0) {
char result[BUFLEN];
sprintf(result, "%d\n", getpid());
result[BUFLEN] = '\0';
fprintf(conn, result); // print result to stream.
printf("I have written %s", result);
//fclose(conn); ->problema
}


Dopo aver accettato la connessione creo il file descriptor e va tutto bene. Poi confronto la stringa con 1 se il confronto va bene dovrei inviare il mio pid. Bene il messaggio viene inviato solamente se al termine inserisco la chiamata fclose(fd). Ma io non voglio chiudere il filedescriptor. Qualcuno sa dirmi il motivo?

cionci
24-12-2007, 15:25
Ciao a tutti,
ho un grave problema con i socket. Sto scrivendo la parte "server" del mio programma, ma sto incontrando notevoli difficoltà. Ho questo pezzo di codice che mi danna:


sock_fd = accept(sock_id, NULL, NULL);
if (sock_fd == -1)
die("accept failed");

conn = fdopen(sock_fd, "r+"); // open write read-wrtie stream.

if (conn == NULL)
die("fdopen failed");
fgets(buf, BUFLEN, conn); // read characters from stream.


if (strncmp(buf, "1", 1) == 0) {
char result[BUFLEN];
sprintf(result, "%d\n", getpid());
result[BUFLEN] = '\0';
fprintf(conn, result); // print result to stream.
printf("I have written %s", result);
//fclose(conn); ->problema
}


Dopo aver accettato la connessione creo il file descriptor e va tutto bene. Poi confronto la stringa con 1 se il confronto va bene dovrei inviare il mio pid. Bene il messaggio viene inviato solamente se al termine inserisco la chiamata fclose(fd). Ma io non voglio chiudere il filedescriptor. Qualcuno sa dirmi il motivo?
Suppongo che scrivendo nel socket con la printf il socket sottosta alle stesse regole dell'output su console, cioè il flush dei dati avviene solamente dopo un carattere \n oppure al momento della chiusura.
Come mai stai usando fprintf per scrivere sul socket ? Sinceramente io preferisco usare le classi read, write o meglio send e recv.

magix2003
24-12-2007, 16:53
Cavolo grazie... Io pensavo bastasse mettere la new line alla fine della stringa, invece bisogna sempre dare un fprintf(fd, "\n")

Questo pezzo di codice è tratto da un progetto che devo fare per l'università (un cracker di password MD5 distribuito); il mio assistente aveva dato un pezzo di codice di esempio e usava fprintf; quindi ho continuato ad usarla.

Grazie mille

Ciao

ilsensine
25-12-2007, 21:10
Anche una fflush dovrebbe risolvere.

Visto che stai scrivendo il codice ex novo, dovresti _seriamente_ considerare l'utilizzo delle funzioni socket native ed evitare la fdopen su un socket descriptor. Non hai alcun vantaggio in cambio, solo problemi e limitazioni.

ilsensine
25-12-2007, 21:15
char result[BUFLEN];
result[BUFLEN] = '\0';


Stack overflow

magix2003
26-12-2007, 07:58
Stack overflow

Grazie, me ne ero già accorto. Siccome la data di consegna del progetto si avvicina, prima voglio finire il programma e poi inizierò a fare queste rifiniture.

Che vantaggi ci sono ad usare le send e recv?

cionci
26-12-2007, 09:28
Che vantaggi ci sono ad usare le send e recv?
Prima di tutto non lavori solo con le stringhe, ma puoi passare anche strutture dati binarie. Certo lo puoi fare anche con fwrite, ma diventa complesso gestire stringhe e dati binari insieme per il ricevente.
Al contrario con send e recv ti fai una struct che riempi con i dati da inviare (attenzione alle stringhe a dimensione non costante che vanno scritte a parte) e diventa un vero e proprio protocollo di comunicazione...un protocollo con fprintf diventa una cosa indecifrabile :)

ilsensine
26-12-2007, 09:55
Che vantaggi ci sono ad usare le send e recv?
Che vantaggi ci sono ad usare un ulteriore strato di astrazione che non offre praticamente funzionalità aggiuntive? (nota che la fprintf può essere sostituita con la dprintf).
Inoltre operando direttamente sugli fd, puoi usare funzioni tipo poll/select; send/recv dispongono un campo "flag" dove puoi specificare parametri specifici per i socket; hai a disposizione alcune ioctl per conoscere lo stato del buffer in ingresso; eccetera.

71104
26-12-2007, 10:11
Stack overflow esagerato :asd: