socket学习笔记——线程(聊天程序)

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 }
原文地址:https://www.cnblogs.com/boyiliushui/p/4737765.html