codice:
/* client.c */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#define PORTNUM 15000
int crea_socket(char *dest, int porta)
{
struct sockaddr_in addr;
struct hostent *h;
int sock_id;
addr.sin_family=AF_INET;
addr.sin_port=htons(porta);
h=gethostbyname(dest);
if(h==0)
{
printf("Connessione IP alfanumerico fallito\n\n");
printf("Terminazione\n");
exit(-1);
}
bcopy(h->h_addr,&addr.sin_addr,h->h_length);
if( (sock_id=socket(AF_INET,SOCK_STREAM,0))<0 )
{
perror("Errore nella creazione del socket");
printf("\n\nTerminazione\n");
exit(-1);
}
if(connect(sock_id,(struct sockaddr *)&addr,sizeof(addr))<0)
{
perror("Errore nella connessione");
printf("\n\nTerminazione\n");
exit(-1);
}
return sock_id;
}
ssize_t invia(int socket,char *mess)
{
size_t nsin;
ssize_t nscritti;
nsin=strlen(mess);
while(nsin>0)
{
if( (nscritti=write(socket,mess,strlen(mess)))<0)
{
if (errno==EINTR)
continue;
else
return(nscritti);
}
nsin=nsin-nscritti;
mess=mess+nscritti;
}
return (strlen(mess));
}
int main(int argc, char *argv[])
{
int sock_id;
char mess[512];
int exit_cond=0;
if(argc!=2)
{
printf("Uso corretto: client nickname");
printf("\n\nTerminazione\n");
exit(-1);
}
if( (sock_id=crea_socket("127.0.0.1",PORTNUM))<0 )
{
perror("Errore nella creazione del socket");
printf("\n\nTerminazione\n");
exit(-1);
}
while(exit_cond==0)
{
printf("Messaggio da inviare: ");
fgets(mess,512,stdin);
if(strcmp(mess,"quit\n")==0)
exit_cond=1;
write(sock_id,mess,strlen(mess));
printf("Messaggio inviato\n");
}
printf("Chat terminata per %s\n",argv[1]);
close(sock_id);
exit(0);
}
/* server.c */
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <pthread.h>
#include <time.h>
#define PORTNUM 15000
#define MAX_NUM_CLIENTS 50
void fireman()
{
union wait wstatus;
while(wait3(&wstatus,WNOHANG,NULL)>0);
}
int crea_socket(int porta)
{
int sock_id;
struct sockaddr_in addr;
if( (sock_id=socket(AF_INET,SOCK_STREAM,0))<0 )
{
perror("Errore nella creazione del socket");
printf("\n\nTerminazione\n");
exit(-1);
}
memset((void *)&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=INADDR_ANY;
addr.sin_port=htons(porta);
if(bind(sock_id,(struct sockaddr *)&addr,sizeof(addr)))
{
perror("Errore di Binding");
printf("\n\nTerminazione\n");
exit(-1);
}
if(listen(sock_id,MAX_NUM_CLIENTS)<0)
{
perror("Errore di listening");
printf("\n\nTerminazione\n");
exit(-1);
}
return sock_id;
}
ssize_t leggi(int desc, char *buf, size_t count)
{
int nletti=0;
int da_legg=0;
while(nletti < count)
{
if( (da_legg=read(desc, buf, count-nletti))<0 )
{
nletti=nletti+da_legg;
buf=buf+da_legg;
}
if(da_legg<0)
return(-1);
}
return (nletti);
}
struct thread_data {
int thread_id;
int sock_id;
};
pthread_mutex_t mutexdata;
struct thread_data thread_buf[MAX_NUM_CLIENTS];
struct timespec delay;
int users=0;
pthread_t threads[MAX_NUM_CLIENTS];
void *servi(void *thread_arg)
{
struct thread_data *mydata;
mydata=(struct thread_data *) thread_arg;
int thread_id=mydata->thread_id;
int sock_id=mydata->sock_id;
int newsock_id;
int exit_cond=0;
int letti;
char buffer[512];
pthread_mutex_lock(&mutexdata);
users++;
pthread_mutex_unlock(&mutexdata);
printf("Usr=%d\n",users);
printf("Thread %d: Socket identity: %d\n\n",thread_id,sock_id);
while(exit_cond==0)
{
if( (letti=read(sock_id,buffer,sizeof(buffer)))<0 )
{
perror("Errore di lettura");
printf("\n\nTerminazione\n");
exit(-1);
}
if(strcmp(buffer,"quit\n")==0)
{
printf("quit\n");
exit_cond=1;
printf("%d\n",exit_cond);
}
else
{
printf("%s\n",buffer);
}
}
printf("Sto uscendo");
pthread_mutex_lock(&mutexdata);
printf("Modifico users");
users--;
pthread_mutex_unlock(&mutexdata);
printf("exit");
pthread_exit(NULL);
close(newsock_id);
return;
}
int main(int argc, char *argv[])
{
char buffer[512];
int sock_id, newsock_id;
int exit_cond=0;
int exit_while=0;
int letti;
int rc;
int status;
int inizio=0;
delay.tv_sec=2;
delay.tv_nsec=0;
if(argc!=1)
{
printf("Uso corretto: server ");
printf("\n\nTerminazione\n");
exit(-1);
}
sock_id=crea_socket(PORTNUM);
signal(SIGCHLD,fireman);
while((inizio==0) || (users>0 && users<(MAX_NUM_CLIENTS+1)))
{
inizio=1;
printf("Users=%d\n",users);
if( (newsock_id=accept(sock_id,0,0))<0 )
{
perror("Errore nell'accettazione della connessione");
printf("\n\nTerminazione\n");
exit(-1);
}
thread_buf[users].thread_id=users;
thread_buf[users].sock_id=newsock_id;
if( (rc=pthread_create(&threads[users],NULL,servi,(void *) &thread_buf[users]))<0 )
{
perror("Errore nella creazione del thread");
printf("\n\nTerminazione\n");
exit(-1);
}
}
pthread_mutex_destroy(&mutexdata);
printf("Fine della comunicazione\n");
exit(0);
}