linux 网络编程:使用两线程实现socket同时收发数据

2019-07-13 03:59发布

转载:http://blog.csdn.net/li_wen01/article/details/52665505 工作中最近有使用到socket 向客户端同时发送和接收数据,因为是嵌入式linux设备,且要求只能同时一个客户端连接该端口。考虑到节省系统资源,只创建了两个线程分别实现服务端的收发数据。下面直接上代码,该代码为在PC机上程序,已作详细注释。 server.c [objc] view plain copy
  1. #include  
  2. #include  
  3. #include  
  4. #include  
  5. #include  
  6. #include  
  7. #include  
  8. #include  
  9. #include     
  10. #include      
  11. #include  
  12. #include  
  13. #include  
  14. #include  
  15.   
  16. #define MAXLINE 256  
  17. #define PORT    6666  
  18. int listenfd;  
  19. int connfd;  
  20. pthread_t read_id, write_id;  
  21.   
  22. /* 
  23. linux ctrl + C 会产生 SIGINT信号 
  24. 接收到SIGINT 信号进入该函数 
  25. */  
  26. void stop(int signo)  
  27. {  
  28.     printf("stop ");  
  29.     close(connfd);    
  30.     close(listenfd);  
  31.      _exit(0);  
  32. }  
  33.   
  34. /* 
  35. 当客户端断开连接的时候, 
  36. 在服务端socket send进程可以收到收到信号SIGPIPE, 
  37. 收到SIGPIPE信号进入该函数结束创建的线程。 
  38. */  
  39. void signal_pipe(int signo)  
  40. {  
  41.     pthread_kill(read_id,SIGQUIT);//向read线程发送SIGQUIT  
  42.     pthread_join(read_id,NULL);   //阻塞线程运行,直到read 线程退出。  
  43.       
  44.     close(connfd);                //关闭连接  
  45.     printf("read pthread out  ");  
  46.       
  47.     pthread_exit(0);              //结束write 线程  
  48. }  
  49.   
  50. /* 
  51. read 线程接收到SIGQUIT信号, 
  52. 执行线程退出操作 
  53. */  
  54. void pthread_out(int signo)  
  55. {  
  56.     pthread_exit(0);  
  57. }  
  58.   
  59. /* 
  60. read 线程执行函数 
  61. */  
  62. void* read_func(void* arg)  
  63. {  
  64.     char readbuff[MAXLINE];  
  65.     int n = 0;  
  66.     int fd;  
  67.   
  68.     fd = *(int*)arg;    /*main 主进程传递过来的连接文件描述符*/  
  69.     memset(&readbuff,0,sizeof(readbuff));  
  70.   
  71.     signal(SIGQUIT,pthread_out); /* 注册SIGQUIT 信号*/   
  72.     while(1)  
  73.     {  
  74.         n = recv(fd, readbuff, MAXLINE, 0);  /*recv 在这里是阻塞运行*/  
  75.         if(n > 0)  
  76.         {  
  77.             printf("server recv data: %s  ",readbuff);  
  78.         }  
  79.     };  
  80. }  
  81. /* 
  82. write 线程执行函数 
  83. */  
  84. void* write_func(void* arg)  
  85. {  
  86.     char writebuff[MAXLINE];  
  87.     char* write = "I am server";  
  88.     unsigned char i = 0;  
  89.     int num = 0;  
  90.     int fd;  
  91.   
  92.     fd = *(int*)arg;  
  93.     memset(&writebuff,0,sizeof(writebuff));  
  94.       
  95.     signal(SIGPIPE,signal_pipe); /* 注册 SIGPIPE信号 */  
  96.     while(1)  
  97.     {  
  98.         sleep(1);  
  99.         send(fd,write,strlen(write)+1,0);/*向客户端发送数据*/