|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Sep 2006
Città: Bologna/Milano
Messaggi: 525
|
[c++] socket...
vi allego due stupidissimi programmi che dovrebbero fare uno stupidissimo collegamento server/client in cui il client manda al server il messaggio "ciao!", ma sto ciao non arriva
ps: ho provato a connettermi al server con TELNET 127.0.0.1 1000 e se gli mando qualche stringa la legge perfettamente... quindi credo che il problema sia nel client!!!! |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Jan 2006
Messaggi: 2722
|
Beh sì, il client non è molto elegante... A parte il fatto che, nel main del client, non controlli in valore tornato dalla tua funzione InitClientSocket(), quindi non sai se il socket è stato creato con successo, esso non viene comunque creato con successo
Ti faccio notare che, dal momento che passi alla suddetta funzione un IP in formato puntato (nel tuo caso chiami "InitClientSocket("127.0.0.1", 1000);"), ti conviene fare, al posto della riga 118 di sock.cpp: Codice:
if ((saClient.sin_addr.s_addr = inet_addr(pHost) == INADDR_NONE)
{
// Gestione errore di ip non valido.
return NULL;
}
Infatti usare una "gethostbyname()" su un indirizzo ip è praticamente inutile (anche se nessuno ce lo vieta...), dal momento che la funzione serve appunto per convertire un nome host in un indirizzo ip... Comunque, possiamo anche supporre di non sapere se il parametro pHost sia un nome host o un indirizzo in notazione puntata. Un modo a mio parere "elegante" di gestire la situazione (anche come velocità di esecuzione), può essere la seguente: Codice:
#define MAX_BUFLENGTH 256
...
saClient.sin_family = AF_INET;
saClient.sin_port = htons(iPort);
if (isalpha(pHost[0]))
{
// Rimuovo lo '\n' se presente.
if (pHost[strlnen(pHost, MAX_BUFLENGTH) - 1] == '\n')
pHost[strnlen(pHost, MAX_BUFLENGTH) - 1] = '\0';
pHostinfo = gethostbyname(pHost);
if (pHostinfo == NULL)
{
// Eventuale gestione errore...
return NULL;
}
// NOTA: nella definizione di sockaddr_in, h_addr = h_addr_list[0]
// h_addr è presente solo per retrocompatibilità, meglio non usarlo...
char *ip = inet_ntoa (*(struct in_addr *)pHostinfo->h_addr_list[0]);
if (ip == NULL)
{
// Eventuale gestione errore...
return NULL;
}
if ((saClient.sin_addr.s_addr = inet_addr(ip) == INADDR_NONE)
{
// Eventuale gestione errore...
return NULL;
}
}
else
if ((saClient.sin_addr.s_addr = inet_addr(pHost) == INADDR_NONE)
{
// Eventuale gestione errore...
return NULL;
}
...
Codice:
#define MAX_BUFLENGTH 256
...
saClient.sin_family = AF_INET;
saClient.sin_port = htons(iPort);
// Rimuovo lo '\n' se presente.
if (pHost[strlnen(pHost, MAX_BUFLENGTH) - 1] == '\n')
pHost[strnlen(pHost, MAX_BUFLENGTH) - 1] = '\0';
pHostinfo = gethostbyname(pHost);
if (pHostinfo == NULL)
{
// Eventuale gestione errore...
return NULL;
}
// NOTA: nella definizione di sockaddr_in, h_addr = h_addr_list[0]
// h_addr è presente solo per retrocompatibilità, meglio non usarlo...
char *ip = inet_ntoa (*(struct in_addr *)pHostinfo->h_addr_list[0]);
if (ip == NULL)
{
// Eventuale gestione errore...
return NULL;
}
if ((saClient.sin_addr.s_addr = inet_addr(ip) == INADDR_NONE)
{
// Eventuale gestione errore...
return NULL;
}
Codice:
saClient.sin_addr=*((struct in_addr *)pHostinfo->h_addr); Ah, ricordati ogni tanto di fare un po' di controllo errori eh! EDIT: Nel codice che ho postato, ho lasciato i nomi delle variabili identiche a quelle presenti nel codice da te allegato. Quindi puoi fare anche un mero copia-incolla, ma ti consiglio sempre di analizzare il tutto prima
__________________
- Spesso gli errori sono solo i passi intermedi che portano al fallimento totale. - A volte penso che la prova piu' sicura che esiste da qualche parte una forma di vita intelligente e' il fatto che non ha mai tentato di mettersi in contatto con noi. -- Bill Watterson Ultima modifica di -fidel- : 21-10-2006 alle 02:16. |
|
|
|
|
|
#3 | |
|
Senior Member
Iscritto dal: Feb 2002
Messaggi: 906
|
Quote:
io ho usato la 12345 e funziona tutto a meraviglia stampa in modo sleeppato il numero 5 ... bravo mamo139... non ti complicare troppo la vita per vedere il ciao fai queste modifiche: 1. metti come porta 12345 sul client e il server 2. correggi: // int x = SendTo(sock, "ciao!"); int x = send(sock, "ciao!", 5, 0); 3. correggi: if (recv(ClientSock,pBuffer, 5, 0) == SERVER_SOCKET_ERROR){ ClientConnesso = false; continue; } pBuffer[5]= '\0'; printf("the message is: %s",pBuffer); #ifdef DEBUG_MODE // printf("the message is: %s",pBuffer); //MessageBox(NULL, pBuffer, "Protocollo", MB_OK); #endif N.B. togli i void che non servono. in + chi legge i listati non capisce quale è il client e il server, indenta il code. vatti a studiare: RecvFrom, recv SendTo, send SOCK_STREAM o SOCK_DGRAM IPPROTO_TCP ecc ecc UDP TCP... ti dice nulla? x il resto n.d.r Ultima modifica di okay : 21-10-2006 alle 02:39. |
|
|
|
|
|
|
#4 | ||
|
Senior Member
Iscritto dal: Jan 2006
Messaggi: 2722
|
Quote:
Quote:
Mi sa che non hai afferato il problema. Comunque l'errore più grosso (che pregiudica il funzionamento) è quello che ho esposto prima.
__________________
- Spesso gli errori sono solo i passi intermedi che portano al fallimento totale. - A volte penso che la prova piu' sicura che esiste da qualche parte una forma di vita intelligente e' il fatto che non ha mai tentato di mettersi in contatto con noi. -- Bill Watterson Ultima modifica di -fidel- : 21-10-2006 alle 02:30. |
||
|
|
|
|
|
#5 | ||
|
Senior Member
Iscritto dal: Feb 2002
Messaggi: 906
|
Quote:
Quote:
Cmq non passando per: int RecvFrom(SOCKET s, char *pBuffer) ... e usando una recv e una send risolve il problema. |
||
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Jan 2006
Messaggi: 2722
|
@ mamo:
Se può interessarti, visita questo thread: http://www.hwupgrade.it/forum/showth...5&page=1&pp=20 Oltre al fatto che la sua lettura penso possa esserti di aiuto, nel mio post #29 trovi allegati un client ed un server, precompilati e con sorgenti ampiamente (ma davvero ampiamente Magari possono esserti di ulteriore aiuto. Mi pare che in quelli non uso la gethostbyname, perchè richiedevo come parametro del client l'ip del server. Puoi provare a prendere quel codice e modificarlo inserendo la gethostbyname() (con uno dei due metodi esposti nel mio precedente post).
__________________
- Spesso gli errori sono solo i passi intermedi che portano al fallimento totale. - A volte penso che la prova piu' sicura che esiste da qualche parte una forma di vita intelligente e' il fatto che non ha mai tentato di mettersi in contatto con noi. -- Bill Watterson |
|
|
|
|
|
#7 | ||
|
Senior Member
Iscritto dal: Jan 2006
Messaggi: 2722
|
Quote:
Quote:
Ripeto, il problema e su saClient.sin_addr....
__________________
- Spesso gli errori sono solo i passi intermedi che portano al fallimento totale. - A volte penso che la prova piu' sicura che esiste da qualche parte una forma di vita intelligente e' il fatto che non ha mai tentato di mettersi in contatto con noi. -- Bill Watterson Ultima modifica di -fidel- : 21-10-2006 alle 03:00. |
||
|
|
|
|
|
#8 | |
|
Senior Member
Iscritto dal: Feb 2002
Messaggi: 906
|
Quote:
sulla Client.sin_addr.. nessun problema visto che il "ciao!" arriva. su 127.0.0.1 in locale funziona. Forse intendi che con ip dinamico avrebbe dei problemi? invece che 127.0.0.1? |
|
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Jan 2006
Messaggi: 2722
|
Bene, ho provato a compilare ed usare il codice postato da mamo.
Ad esempio, ciò che tu hai fatto: Codice:
saClient.sin_addr=*((struct in_addr *)pHostinfo->h_addr); Il problema risiede esclusivamente nel codice della RecvFrom che hai scritto. Infatti quella funzione ritorna solo nel caso di uno \n, che il client non manda mai. Ecco perchè con telnet funziona e con il client no... Prova ad esempio a commentare le due righe "do" e "while (...)", e vedrai che funziona. Comunque puoi notevolmente migliorare tutto il codice Ah, quello che ho scritto prima è sempre valido, e ti permette di fare più controlli di errore sui dati passati (ma puoi farli anche sulla struct hosthent* tornata dalla gethostbyname() nello stesso modo in cui li ho fatti io, quindi scegli tu).
__________________
- Spesso gli errori sono solo i passi intermedi che portano al fallimento totale. - A volte penso che la prova piu' sicura che esiste da qualche parte una forma di vita intelligente e' il fatto che non ha mai tentato di mettersi in contatto con noi. -- Bill Watterson Ultima modifica di -fidel- : 21-10-2006 alle 14:34. |
|
|
|
|
|
#10 | |
|
Senior Member
Iscritto dal: Jan 2006
Messaggi: 2722
|
Quote:
__________________
- Spesso gli errori sono solo i passi intermedi che portano al fallimento totale. - A volte penso che la prova piu' sicura che esiste da qualche parte una forma di vita intelligente e' il fatto che non ha mai tentato di mettersi in contatto con noi. -- Bill Watterson Ultima modifica di -fidel- : 21-10-2006 alle 14:17. |
|
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Sep 2006
Città: Bologna/Milano
Messaggi: 525
|
eheh... ok problema risolto, grazie mille...
xò ce ne è un altro... ho fatto una prova: ho solo aggiunto '\n' alla stringa ciao e quindi ora i segnali arrivano, solo che se chiudo il client il server non mi dice che è stato chiusa la connessione... mentre se chiudo telnet me lo dice... come mai?? EDIT niente niente ho risolto Ultima modifica di mamo139 : 21-10-2006 alle 15:29. |
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Sep 2006
Città: Bologna/Milano
Messaggi: 525
|
ora stavo provando a creare due funzioni, una nel client, l'altra nel serve per fare in modo che i due programmi si possano scambiare dei file... ma nn funzionano
Codice:
int invio_file(SOCKET sockinvio){
char thisbuffer[1000];
char nomefile[1000];
char nomefileclient[1000];
int nBytesP;
strcpy(thisbuffer,"");
strcat(thisbuffer,"nomefile:");
printf(thisbuffer);//richiesta di inserimento nome file
strcpy(thisbuffer,""); //cancelliamo buffer
strcpy(nomefile,"");
strcpy(nomefileclient,"");
gets(nomefile); //prendiamo nome del file
//riceviamo richiesta di invio nome destinazione
nBytesP = recv(sockinvio, thisbuffer, BUFFERSIZE, 0);
thisbuffer[nBytesP] = '\0';
printf(thisbuffer); //richiesta del nome del file da dare al client
gets(nomefileclient);
SendTo(sockinvio,nomefileclient);
//*** inizio invio file ***//
char filebuffer[10];
FILE *file = fopen(nomefile,"rb");
if (file==NULL) return 0;
fseek (file , 0 , SEEK_END);
long lSize = ftell (file);
rewind (file);
for(int x = 0; x < lSize ; x++) {
fread( filebuffer, 1, 1, file);
SendTo(sockinvio,filebuffer);
}
fclose(file);
#ifdef DEBUG_MODE
system("pause");
#endif
return 1;
}
Codice:
void ricezione_file(SOCKET sockinvio){
int nBytesP;
char thisbuffer[1000];
char nomefile[1000];
strcpy(nomefile,"");
strcpy(thisbuffer,"");
strcat(thisbuffer,"url del file inviato:"); //invio richiesta nome file
SendTo(sockinvio,thisbuffer);
strcpy(thisbuffer,"");//cancellazione buffer
nBytesP = recv(sockinvio, nomefile, BUFFERSIZE, 0); //ricezione nome file
nomefile[nBytesP] = '\0';
#ifdef DEBUG_MODE
printf("nome file: %s",nomefile);
#endif
//*** inizio ricezione file ***//
char filebuffer[10];
FILE *file;
file = fopen (nomefile,"wb");
while(recv(sockinvio,filebuffer, 1, 0) != 0){ //scriviamo tutto il file...
filebuffer[1] = '\0';
fprintf(file,"%s",filebuffer);
}
fclose (file);
#ifdef DEBUG_MODE
system("pause");
#endif
}
|
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: Sep 2006
Città: Bologna/Milano
Messaggi: 525
|
ok problema risolto... grazie cmq
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 16:56.



















