PDA

Visualizza la versione completa : Client in C


Kamui
28-02-2003, 18:28
Sto tentando di compilare questo client in C per Unix, usando gcc :d56:

Il codice non dovrebbe contenere errori, dato che copiato da un libro, eppure il debugger mi scassa e non mi d l'eseguibile...
ecco il codice:


#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>

#define PORT 4000 //port pubblico del server

void addr_initialize();

int main (int argc, char* argv[])
{
struct sockaddr_in server_addr;
struct sockaddr_in my_addr;
int my_addr_len = sizeof(my_addr);
int error;
int sd;

addr_initialize(&server_addr, PORT, (long)inet_addr(argv[1]));
sd = socket (AF_INET, SOCK_STREAM, 0);
error = connect(sd, &server_addr, sizeof(server_addr));

if(error==0){
printf("\nConnessione eseguita con successo\n");
getsockname(sd, &my_addr, &my_addr_len);
printf("Il port e' il numero %d", ntohs(my_addr.sin_port));
}
else{
printf("\nRilevato errore: %i\n\n", error);
}
close(sd);

return 0;
}

Ed ecco cosa mi dice il debugger:

client.c: In function `main':
client.c:29: warning: passing arg 2 of `connect' from incompatible pointer type
client.c:33: warning: passing arg 2 of `getsockname' from incompatible pointer type
/tmp/ccsiYuLq.o: In function `main':
/home/Kamui/Documents/Client/client.c:27: undefined reference to `addr_initialize'
collect2: ld returned 1 exit status


A parte i due warnings che ci possono stare... non capisco il perch dei due ultimi errori, che non vengono rilevati normalmente dal gcc all'interno del file client.c, ma hanno un path prima, e poi "collect2" che non so che significhi :confused:

Chi sa aiutarmi? :ciauz:

Michele Facchin
28-02-2003, 19:07
void addr_initialize ( );


Tu hai questo prototipo, e poi nel codice scrivi:



addr_initialize ( &server_addr , PORT , ( long ) inet_addr ( argv [ 1 ] ) );


Passandogli tre parametri che non hai dichiarato,come f ad andarti?
Devi rivedere meglio il codice..
Comunque se ti serve un client di esmpio prova questo che funziona:



#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>

#define MAXB 8000

int main ( void ) {
int sd;
struct sockaddr_in client;
struct hostent * hp;
unsigned short port = 25; /* Simple Mail Transfer Protocol */
char buff [ MAXB ];
hp = gethostbyname( "smtp.tin.it" );
bzero ( & client , sizeof ( client ) );
client.sin_family = AF_INET;
client.sin_port = htons ( port );
client.sin_addr.s_addr = ( ( struct in_addr * ) ( hp -> h_addr ) ) -> s_addr;
if ( ( sd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 )
fprintf ( stdout , "Errore nella creazione del socket\n" );
else
fprintf ( stdout , "Socket creato!\n" );
if ( connect ( sd , ( struct sockaddr * ) & client , sizeof ( client ) ) < 0 )
fprintf ( stdout , "Errore nella connessione!\n" );
send ( sd, "Helo tin.it" , strlen ( "HELO tin.it" ) + 1 , 0 );
recv ( sd , buff , sizeof ( buff ) , 0 );
fprintf( stdout , "Risposta: %s\n" , buff );
close ( sd );
return ( 0 );
}

Kamui
28-02-2003, 19:20
Non c'entra il prototipo, prima di copiare dal libro l'avevo fatto a modo mio col prototipo bello definito, ma non cambia assolutamente nulla :quipy:
il codice dovrebbe essere giusto, o per lo meno eseguibile, credo di avere qualche casino in Linux ma non so cosa...:dh:

Michele Facchin
28-02-2003, 19:23
Il prototipo non centra?
Vabbene allora, continua a trovare la soluzione a modo tuo :quipy:
Prova comunque il codice che ti ho pastato e dimmi se ti funziona :-)

Kamui
28-02-2003, 20:03
Non la trovo a modo mio, ho copiato dal libro :sonno: e ho pure provato col prototipo definito, ma non cambia nulla nel debugging :mad:

Il tuo codice funziona, solo 4 warnings
client2.c: In function `main':
client2.c:17: warning: implicit declaration of function `bzero'
client2.c:27: warning: implicit declaration of function `strlen'
client2.c:30: warning: implicit declaration of function `close'
client2.c:32:2: warning: no newline at end of file

il problema che io vorrei sapere dov' sbagliato il "mio"...
:( :bh:

Michele Facchin
28-02-2003, 20:14
Te lo ripeto: Sbagli il prototipooo :)


#include <stdio.h>

void parappapa ( );

int main ( void ) {
int a = 999 , b = 1000 , c = 1001;
printf ( "mille mila.." );
parappapa ( a , b , c );
return ( 0 );
}


Il tuo codice sopra assomiglia a questo, cio sbagliatissimo :quipy:
Sbaglia la dichiarazione del prototipo della funzione void addr_initialize ( );

Kamui
28-02-2003, 20:28
Guarda, io all'inizio, non sapendo bene com'era, avevo addirittura scritto tutta la funzione l, altro che prototipo! :D poi nell'esercizio del prof e in quello del libro vedo che non c' nulla tra gli argomenti passati e l'ho copiato cos, per farlo identico al librom, sicuro che fosse giusto... cmq appunto ho messo anche il prototipo, e ricompilato, e il debug non cambia!
Magari sbagliato ancora, l'ho messo cos:


void addr_initialize(struct sockaddr_in*, int, long);

come devo farlo? :confused:

Tu hai provato a compilarlo sulla tua macchina?? ti d lo stesso debug?? :confused:

:ciauz:

Michele Facchin
28-02-2003, 20:33
Non ho provato, comunque questo nuovo prototipo gi meglio.
Cmq adesso che hai dichiarato sto prototipo devi scrivere la funzione addr_initialize, dopo ripasta il codice completo anche di questa funzione mancante.

Kamui
28-02-2003, 20:47
Ah quindi devo mettercela la funzione! Infatti ora va! :D
Avevo pure dimenticato di scrivere una r che mi dava un ultimo errore, ma adesso ha creato l'eseguibile... ora mi butto sul server e poi li provo! Grazie dell'aiuto! :)

Kamui
28-02-2003, 21:06
Compilati entrambi, senza errori, per non riesco a connetterli...:d56:

CLIENT:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>

#define PORT 4000 //port pubblico del server

void addr_initialize(struct sockaddr_in*, int, long);

int main (int argc, char* argv[])
{
struct sockaddr_in server_addr;
struct sockaddr_in my_addr;
int my_addr_len = sizeof(my_addr);
int error;
int sd;

addr_initialize(&server_addr, PORT, (long)inet_addr(argv[1]));
sd = socket (AF_INET, SOCK_STREAM, 0);
error = connect(sd, /*(struct sockaddr*)*/&server_addr, sizeof(server_addr));

if(error==0){
printf("\nConnessione eseguita con successo\n");
getsockname(sd, &my_addr, &my_addr_len);
printf("Il port e' il numero %d", ntohs(my_addr.sin_port));
}
else{
printf(/*"%s",*/"\nRilevato errore: %i\n\n", error);
}
close(sd);

return 0;
}

void addr_initialize(struct sockaddr_in* indirizzo, int port, long IPaddr)
{
indirizzo->sin_family = AF_INET;
indirizzo->sin_port = htons((u_short)port);
indirizzo->sin_addr.s_addr = IPaddr;
}

SERVER:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

#define PORT 4000
#define MAXCONN 5

/*struct sockaddr_in{
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};*/

void addr_initialize(struct sockaddr_in*, int, long);

int main(int argc, char* argv[])
{
int sd, new_sd, bind_result,listen_result;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
int client_len = sizeof(client_addr);

addr_initialize(&server_addr, PORT, INADDR_ANY);
sd = socket(AF_INET, SOCK_STREAM, 0);

if (sd == -1)
{ printf("Rilevato errore di socket\n");
exit(0);
}

bind_result = bind(sd, (struct sockaddr*)&server_addr, sizeof(server_addr));

if (bind_result!=0)
{
printf("Rilevato errore di bind\n");
exit(0);
}

listen_result = listen(sd, MAXCONN);
new_sd = accept(sd, (struct sockaddr*)&client_addr, &client_len);

printf("Sono in attesa di connessione\nIl port del Client e' &d", ntohs(client_addr.sin_port));

close(new_sd);
close(sd);
return 1;
}

void addr_initialize(struct sockaddr_in* indirizzo, int port, long IPaddr)
{
indirizzo->sin_family = AF_INET;
indirizzo->sin_port = htons((u_short)port);
indirizzo->sin_addr.s_addr = IPaddr;
}


Eseguo il server:

[Kamui@localhost Server]$ ./server
Rilevato errore di bind
[Kamui@localhost Server]$


Eseguo il client:

[Kamui@localhost Client]$ ./client
Segmentation fault
[Kamui@localhost Client]$


A cosa dovuto? dove sbaglio? :master:

Loading