zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    【11.5】生成器进阶--send、close和throw方法
    【11.4】协程是什么?
    【python】IO多路复用(select、poll、epoll)介绍及select、epoll的实现
    【11.3】select+回调+事件循环获取html
    【11.2】C10K问题和io多路复用(select、poll和epoll)
    【11.1】并发、并行、同步、异步、阻塞、非阻塞
    【10.10】进程间通信--Queue、Pipe、Manager
    set autotrace on 报cannot set autotrace 错误解决方法
    通配符获取文件
    日期函数
  • 原文地址:https://www.cnblogs.com/boyiliushui/p/4737765.html
Copyright © 2011-2022 走看看