PDA

View Full Version : [C] collegamento Server Client


Tony Hak
05-06-2010, 12:25
Buongiorno a tutti !
Ho il seguente problema: non riesco a far comunicare il server col client (il client dovrebbe visualizzare l'ora e la data inviati dal server). Il client è rappresentato da un altro pc collegato in Lan col server. Tutto avviene in ambiante UNIX. Il codice in questione del server è il seguente :

#include <sys/socket.h>
#include <sys/un.h>
#include <time.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <netinet/in.h>


#define SOCKET_NAME "/tmp/my_first_socket"
static int gestisci(int);
int main(int argc, char **argv)
{
int listen_sd, connect_sd; // Socket descriptor
struct sockaddr_un my_addr , client_addr;
socklen_t client_len;
my_addr.sun_family = PF_INET;
strcpy(my_addr.sun_path, SOCKET_NAME);

// Server section: create a local socket
if ( (listen_sd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
perror("socket"), exit(1);

// remove socket file if present
unlink(SOCKET_NAME);

// bind socket to pathname

//if ( ( bind ( listen_sd, ( struct sockaddr_in ( 3000, inet_aton ( "127.0.0.1" ) ) ) &my_addr, sizeof ( my_addr ) ) < 0 ) )
// perror("bind"), exit(1);

if ( bind(listen_sd, (struct sockaddr *) &my_addr, sizeof(my_addr)) < 0)
perror("bind"), exit(1);



// put socket in listen state
if ( listen(listen_sd, 1) < 0)
perror("listen"), exit(1);
while (1) {
client_len = sizeof(client_addr);
fprintf(stderr, " sizeof(client_addr)=%d \n", client_len);
if ( (connect_sd = accept(listen_sd, (struct sockaddr *) &client_addr, &client_len)) < 0)
perror("accept"), exit(1);
fprintf(stderr, " new connection \n");
fprintf(stderr, " client address: %100s\n ", client_addr.sun_path);

// handle the connection
gestisci(connect_sd);
close(connect_sd);
}
return 0;
}

int gestisci(int sd)
{
char buf[100];
int n;
time_t ora;
time(&ora);
printf(" Ora: %s\n", ctime_r(&ora, buf));
printf(" Ora: %d\n", strlen(buf));
write(sd, buf, 26);
return 0;
}

dove sbaglio :confused: ? grazie mille :)

Tony Hak
06-06-2010, 10:51
up .. non posso mettere il codice del client perche è sul pc del mio amico :) ... ma quello sembra che funzioni in quanto si mette in attesa del server.

Teo@Unix
06-06-2010, 21:31
up .. non posso mettere il codice del client perche è sul pc del mio amico :) ... ma quello sembra che funzioni in quanto si mette in attesa del server.

il client si mette in attesa? non credo. Chi deve essere preventivamente messo in attesa è semmai il server. Dopo di che si avvia il client.

Puoi specificare l'errore che hai? Così non saprei da dove cominciare...
Semmai può esserti utile scriverti un semplice client base per fare debugging... oppure puoi usare telnet, ma solo per verificare che la connessione avviene...

Tony Hak
07-06-2010, 11:58
abbiamo usato un altro codice. Ecco il codice del server :

/* A simple server in the internet domain using TCP
The port number is passed as an argument */

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <time.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <netinet/in.h>

void error(char *msg)
{
perror(msg);
exit(1);
}

int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno, clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERROR on accept");
bzero(buffer,256);
n = read(newsockfd,buffer,255);
if (n < 0) error("ERROR reading from socket");
printf("Here is the message: %s\n",buffer);
n = write(newsockfd,"I got your message",18);
if (n < 0) error("ERROR writing to socket");
return 0;
}

lo avviamo con riga di comando della shell di linux specificando la porta. Es "./server.out 5300"

ecco il codice del client:

#include <netdb.h>
#include <stdlib.h>
#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <sys/un.h>

#include <time.h>

#include <stdio.h>

#include <unistd.h>

#include <errno.h>

#include <string.h>

#include <fcntl.h>

#include <sys/stat.h>





void error(char *msg)
{
perror(msg);
exit(0);
}

int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;

char buffer[256];
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
printf("Please enter the message: ");
bzero(buffer,256);
fgets(buffer,255,stdin);
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
bzero(buffer,256);
n = read(sockfd,buffer,255);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
return 0;
}

il client lo eseguiamo con riga di comando specificando il nome dell'host e la porta . Es: "./client.out nomehost 5300"

il programma doivrebbe inviare un messaggio al server specificato dal processo del client.

Il problema è che il tutto funziona solo in localhost. Non riusciamo quindi a far comunicare due macchine. L'errore del client è il seguente : NO SUCH HOST.
Grazie per l'aiuto :)

Teo@Unix
07-06-2010, 21:29
Intendi dire che fallisce in questo punto?

if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}


oppure intendi il valore di errno? Semmai controlla anche il valore di errno quando hai l'errore...

se la funzione riportata sopra fallisce può essere che non riesci a risolvere il nome, puoi fare due prove in questo caso, provare con l'indirizzo al posto del nome "./client.out 192.168.y.z 5300"(e se funziona vuol dire che è il nome non risolto) e verificare l'elenco dei server DNS sul tuo computer. Che se il server DHCP è configurato correttamente dovrebbe già essere a posto.

Errno in caso la funzione sopra fallisce avrà uno dei valori seguenti:
HOST_NOT_FOUND,
NO_ADDRESS or NO_DATA ,
NO_RECOVERY,
TRY_AGAIN

Teo@Unix
08-06-2010, 11:29
e verificare l'elenco dei server DNS sul tuo computer. Che se il server DHCP è configurato correttamente dovrebbe già essere a posto.

Che bigolo che sono, in rete locale non ti serve controllare i DNS, a meno che tu abbia un server DNS a casa :D. Ragionavo come se fossi in azienda, il nome dovrebbe comunque risolversi se il file /etc/hosts è configurato correttamente .. prova usando l'indirizzo intanto...

un esempio di file hosts è il seguente (non c'è nessun altro pc oltre localhost, in questo modo la risoluzione non avviene, aggiungi righe dove ho commentato con gli abbinamenti necessari)
~# cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 backtrack bt
# Put here ...

# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
......


dacci un occhio ... se può essere questo il problema ...