Sia il server che il client non sono stati scritti interamente da me, ma solo in parte, ecco il codice
codice:
int main(int argc, char **argv){
pid_t pid;
int listensd, connsd;
struct sockaddr_in servaddr, cliaddr;
socklen_t servaddr_len, cliaddr_len;
char buff[MAXLINE];
char msg[MAXLINE] = "prova di utilizzo di getsockname()";
time_t ticks;
FILE *file;
if( (listensd = socket(AF_INET, SOCK_STREAM, 0)) < 0) err_sys("errore in socket");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(4444);
int tr=1;
// permette il riutilizzo della porta
if (setsockopt(listensd,SOL_SOCKET,SO_REUSEADDR,&tr,sizeof(int)) == -1){
err_sys("errore in setsockopt");
exit(1);
}
if( (bind(listensd, (SA *) &servaddr, sizeof(servaddr))) < 0) err_sys("errore in bind");
if( listen(listensd, LISTENQ) < 0 ) err_sys("errore in listen");
getsockname(listensd, (SA *) &servaddr, &servaddr_len); /* ottiene l'indirizzo IP ed il numero di porta assegnati al socket di ascolto */
inet_ntop(AF_INET, &servaddr.sin_addr, buff, sizeof(buff)); /* estrae dalla struct sockaddr_in l'indirizzo IP e lo copia come stringa in un buffer */
printf("Socket di ascolto: \tIndirizzo IP %s, porta %d\n", buff,ntohs(servaddr.sin_port));
for ( ; ; ) {
cliaddr_len = sizeof(cliaddr);
if( (connsd = accept(listensd, (SA *) &cliaddr, &cliaddr_len)) < 0) err_sys("errore in accept");
getsockname(connsd, (SA *) &servaddr, &servaddr_len); /* ottiene l'indirizzo IP ed il numero di porta assegnati al socket di connessione restituito dall'accept */
inet_ntop(AF_INET, &servaddr.sin_addr, buff, sizeof(buff));
printf("Socket di connessione: \tIndirizzo IP %s, porta %d\n", buff, ntohs(servaddr.sin_port));
printf("Indirizzo del peer: \tIndirizzo IP %s, porta %d\n", inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)), ntohs(cliaddr.sin_port) );
/* stampa indirizzo IP e numero di porta del client.Non serve chiamare getpeername */
if((pid = fork()) == 0 ){
if( close(listensd) == -1 ) err_sys("errore in close");
//-------------------------------------------------------------------------------
char indirizzo[11],i[100],dominio[100],nomefile[10];
int flag=0,n=0;
n = read(connsd, nomefile, sizeof(nomefile));
nomefile[n] = '\0';
printf("%s la cui lunghezza è %d\n",nomefile,strlen(nomefile));
if((file=fopen(nomefile,"r"))==NULL) {
err_sys("File inesistente");
exit(1);
}
getsockname(connsd, (SA *) &servaddr, &servaddr_len);
inet_ntop(AF_INET, &servaddr.sin_addr,indirizzo, sizeof(indirizzo));
// printf("Socket di ascolto: \tIndirizzo IP %s, porta %d\n",indirizzo, ntohs(servaddr.sin_port));
while(fscanf(file,"%s %s",i,dominio)!=EOF){
if ((strcmp(indirizzo,i)) == 0) {
flag=1;
break;
}
}
fclose(file);
if(!flag) strcpy(dominio,"Servizio non disponibile");
sprintf(msg,"%s\n",dominio);
//--------------------------------------------------------------------------------
if( (write(connsd, msg, strlen(msg)) != strlen(msg)) ) err_sys("errore in write");
if( close(connsd) == -1 ) err_sys("errore in close");
exit(0);
}
if( close(connsd) == -1 ) err_sys("errore in close");
}
}
il client
codice:
int main(int argc, char **argv){
int sockd, n;
char buff[MAXLINE], recvline[MAXLINE + 1],sendline[MAXLINE];
struct sockaddr_in servaddr, localaddr, peeraddr;
socklen_t localaddr_len, peeraddr_len;
if ( argc != 3 ) err_quit("utilizzo: sockname_client <IPaddress>");
if ((sockd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) err_sys("errore in socket");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(4444);
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0 ) err_quit("errore in inet_pton per %s", argv[1]);
if ( connect(sockd, (SA *) &servaddr, sizeof(servaddr)) < 0 ) err_sys("errore in connect");
localaddr_len = sizeof(localaddr);
getsockname(sockd, (SA *) &localaddr, &localaddr_len);
/* ottiene l'indirizzo Ip ed il numero di porta assegnati dal sistema operativo alla connessione con endpoint identificato da sockd */
printf("Indirizzo locale: indirizzo IP %s, porta %d\n",inet_ntop(AF_INET, &localaddr.sin_addr, buff, sizeof(buff)),ntohs(localaddr.sin_port));
peeraddr_len = sizeof(peeraddr);
getpeername(sockd, (SA *) &peeraddr, &peeraddr_len);
/* ottiene l'indirizzo Ip ed il numero di porta del peer nella connessione identificata da sockd.L'altro endpoint è identificato dal socket di comunicazione del
server e non dal socket di ascolto. */
printf("Indirizzo del peer: indirizzo IP %s, porta %d\n",inet_ntop(AF_INET, &peeraddr.sin_addr, buff, sizeof(buff)),ntohs(peeraddr.sin_port));
sprintf(sendline,"%s%c",argv[2],'\0');
printf("%s la cui dimensione e %d\n",sendline,strlen(sendline));
if( writen(sockd, sendline, strlen(sendline)) != strlen(sendline) ) err_sys("errore in write");
if( (n = read(sockd, recvline, MAXLINE)) < 0 ) err_sys("errore in read");
recvline[n] = 0;
printf("%s", recvline);
exit(0);
}
l'area delimitata dalla tratteggiatura è stata modificata da me, il resto è stato fatto dal prof.