server.c
1 #include <stdio.h> 2 #include <pthread.h> 3 #include <semaphore.h> 4 #include <arpa/inet.h> 5 #include <unistd.h> 6 #include <sys/socket.h> 7 #include <stdlib.h> 8 #include <string.h> 9 10 #define BUF_SIZE 100 11 #define MAX_CLNT 256 12 13 void *handle_clnt(void* arg); 14 void send_msg(char *msg,int len); 15 void error_handling(char* message); 16 17 int clnt_cnt = 0; 18 int clnt_socks[MAX_CLNT]; 19 pthread_mutex_t mutx; 20 21 int main(int argc,char* argv[]) 22 { 23 int serv_sock,clnt_sock; 24 struct sockaddr_in serv_addr,clnt_addr; 25 int adr_sz; 26 pthread_t t_id; 27 28 if(argc != 2) 29 { 30 printf("usage: %s <port> ",argv[0]); 31 exit(1); 32 } 33 34 pthread_mutex_init(&mutx,NULL); 35 serv_sock = socket(PF_INET,SOCK_STREAM,0); 36 memset(&serv_addr,0,sizeof(serv_addr)); 37 serv_addr.sin_family = AF_INET; 38 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 39 serv_addr.sin_port = htons(atoi(argv[1])); 40 41 if(bind(serv_sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) == -1) 42 error_handling("bind error"); 43 if(listen(serv_sock,5) == -1) 44 error_handling("listen error"); 45 46 while(1) 47 { 48 adr_sz = sizeof(clnt_addr); 49 clnt_sock = accept(serv_sock,(struct sockaddr*)&clnt_addr,&adr_sz); 50 51 pthread_mutex_lock(&mutx); 52 clnt_socks[clnt_cnt++] = clnt_sock; 53 pthread_mutex_unlock(&mutx); 54 55 pthread_create(&t_id,NULL,handle_clnt,(void*)&clnt_sock); 56 pthread_detach(t_id); 57 printf("connected client ip:%s ",inet_ntoa(clnt_addr.sin_addr)); 58 } 59 close(serv_sock); 60 return 0; 61 } 62 63 void* handle_clnt(void* arg) 64 { 65 int clnt_sock = *((int*)arg); 66 int str_len = 0,i; 67 char msg[BUF_SIZE]; 68 69 while((str_len = read(clnt_sock,msg,sizeof(msg))) != 0) 70 send_msg(msg,str_len); 71 pthread_mutex_lock(&mutx); 72 for(i = 0;i < clnt_cnt;i++) 73 { 74 if(clnt_sock == clnt_socks[i]) 75 { 76 while(i++ < clnt_cnt-1) 77 clnt_socks[i] = clnt_socks[i+1]; 78 break; 79 } 80 } 81 clnt_cnt--; 82 pthread_mutex_unlock(&mutx); 83 close(clnt_sock); 84 return NULL; 85 } 86 87 void send_msg(char* msg,int len) 88 { 89 int i; 90 pthread_mutex_lock(&mutx); 91 for(i = 0;i < clnt_cnt;i++) 92 write(clnt_socks[i],msg,len); 93 pthread_mutex_unlock(&mutx); 94 } 95 void error_handling(char* message) 96 { 97 fputs(message,stderr); 98 fputc(' ',stderr); 99 exit(1); 100 }
client.c
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <unistd.h> 5 #include <arpa/inet.h> 6 #include <pthread.h> 7 #include <sys/socket.h> 8 9 #define BUF_SIZE 200 10 #define NAME_SIZE 20 11 12 void *send_msg(void* arg); 13 void *recv_msg(void* arg); 14 void error_handling(char* message); 15 16 char name[NAME_SIZE] = "[DEFAULT]"; 17 char msg[BUF_SIZE]; 18 int main(int argc,char* argv[]) 19 { 20 int sock; 21 struct sockaddr_in serv_addr; 22 pthread_t send_thread,recv_thread; 23 void * thread_return; 24 25 if(argc != 4) 26 { 27 printf("usage: %s <ip> <port> <name> "); 28 exit(1); 29 } 30 31 sprintf(name,"[%s]",argv[3]); 32 sock = socket(PF_INET,SOCK_STREAM,0); 33 34 memset(&serv_addr,0,sizeof(serv_addr)); 35 serv_addr.sin_family = AF_INET; 36 serv_addr.sin_addr.s_addr = inet_addr(argv[1]); 37 serv_addr.sin_port = htons(atoi(argv[2])); 38 39 if(connect(sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) == -1) 40 error_handling("connect error"); 41 42 pthread_create(&send_thread,NULL,send_msg,(void*)&sock); 43 pthread_create(&recv_thread,NULL,recv_msg,(void*)&sock); 44 pthread_join(send_thread,&thread_return); 45 pthread_join(recv_thread,&thread_return); 46 close(sock); 47 return 0; 48 } 49 50 void* send_msg(void* arg) 51 { 52 int sock = *((int*)arg); 53 char name_msg[NAME_SIZE+BUF_SIZE]; 54 while(1) 55 { 56 fgets(msg,BUF_SIZE,stdin); 57 if(!strcmp(msg,"q ") || !strcmp(msg,"Q ")) 58 { 59 close(sock); 60 exit(0); 61 } 62 sprintf(name_msg,"%s %s",name,msg); 63 write(sock,name_msg,strlen(name_msg)); 64 } 65 return NULL; 66 } 67 68 void* recv_msg(void* arg) 69 { 70 int sock = *((int*)arg); 71 char name_msg[BUF_SIZE+NAME_SIZE]; 72 int str_len; 73 while(1) 74 { 75 str_len = read(sock,name_msg,NAME_SIZE+BUF_SIZE-1); 76 if(str_len == -1) 77 return (void*)-1; 78 name_msg[str_len] = 0; 79 fputs(name_msg,stdout); 80 } 81 return NULL; 82 } 83 84 void error_handling(char* message) 85 { 86 fputs(message,stderr); 87 fputc(' ',stderr); 88 exit(1); 89 }