TCP服务器设计范式 - 每个客户连接对应一个线程

4 篇文章 0 订阅
2 篇文章 0 订阅

如果服务器支持线程,那么对于客户/服务进程的架构我们可以采取一个线程处理一个客户连接的设计方案。也就是每当有新的连接请求到达服务器时,服务器会新开一个子线程来专门处理这个连接的信息传递;这种方法类似于服务器为每个客户连接fork一个子进程,但这相对来说更轻量级。

1.首先初始化服务器信息(部分代码):

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. if ((servfd = socket(AF_INET,SOCK_STREAM,0)) < 0)  
  2.     {  
  3.         //建立Socket,程序调用Socket函数,该函数返回一个类似于文件描述符的句柄  
  4.         printf("create socket error!\n");  
  5.         exit(1);  
  6.     }  
  7.     //sin_zero用来将sockaddr_in结构填充到与struct sockaddr同样的长度,可以用bzero()或memset()函数将其置为零  
  8.     bzero(&servaddr,sizeof(servaddr));  
  9.     servaddr.sin_family = AF_INET;  
  10.     servaddr.sin_port = htons(SERVERPORT);  
  11.     servaddr.sin_addr.s_addr = htons(INADDR_ANY);/*系统自动填入本机IP地址 */  
  12.   
  13.     if (bind(servfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)  
  14.     {  
  15.         //服务端通过调用 bind函数来配置本地信息。Bind函数将socket与本机上的一个端口相关联,随后你就可以在该端口监听服务请求。  
  16.         printf("bind to port %d failure!\n",SERVERPORT);  
  17.         exit(1);  
  18.     }  
  19.   
  20.     if (listen(servfd,LENGTH_OF_LISTEN_QUEUE) < 0)  
  21.     {  
  22.        //Listen函数使socket处于被动的监听模式,并为该socket建立一个输入数据队列,将到达的服务请求保存在此队列中,直到程序处理它们。  
  23.            printf("call listen failure!\n");  
  24.            exit(1);  
  25.     }  


2.接着在主线程中监听客户的连接请求:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. while (1)  
  2.     {  
  3.     //服务一直在运行,直到被某个操作或命令终止该进程  
  4.     int recvbytes;  
  5.     socklen_t length = sizeof(cliaddr);  
  6.   
  7.     //accept()函数让服务器接收客户的连接请求  
  8.     int clientfd = accept(servfd,(struct sockaddr*)&cliaddr,&length);  
  9.   
  10.     if (clientfd < 0)  
  11.     {  
  12.         printf("error comes when call accept!\n");  
  13.         break;  
  14.     }  
  15.       
  16.     // 创建用于处理新连接的子线程  
  17.     pthread_t recv_id ;  
  18.     pthread_create(&recv_id, NULL, recv_msg_from_client, &clientfd);  
  19.     }  


3.处理每个客户连接的线程函数(recv_msg_from_clien):

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void* recv_msg_from_client(void* arg)  
  2. {  
  3.     // 分离线程,使主线程不必等待此线程  
  4.     pthread_detach(pthread_self());  
  5.       
  6.     int clientfd = *(int*)arg;  
  7.   
  8.     int recvBytes = 0;  
  9.     char* recvBuf = new char[BUFFER_SIZE];  
  10.     memset(recvBuf, 0, BUFFER_SIZE);  
  11.   
  12.     while(1)  
  13.     {  
  14.         if ((recvBytes=recv(clientfd, recvBuf, BUFFER_SIZE,0)) <= 0)   
  15.         {  
  16.             perror("recv出错!\n");  
  17.             break;  
  18.         }  
  19.         recvBuf[recvBytes]='\0';  
  20.         printf("recvBuf:%s\n", recvBuf);  
  21.     }  
  22.   
  23.     close(clientfd);  
  24.     return NULL;  
  25. }  


据资料《UNIX网络编程》介绍,这种每个客户连接一个线程的设计程序比每个客户连接一个进程的设计程序在实际运行时,速度会快许多倍,消耗的资源也相对少。


原文地址:http://blog.csdn.net/moxiaomomo/article/details/7575991

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值