服务器端如何管理很多个客户端的socket连接? 我想请问大家一个问题,当一个服务器端面临成千上万个客户端的连接,在完成端口后,服务器程序如何管理这成千上万个客户端的连接,保证正常的通讯? 不会是有一万个客户端,就建立一万个线程来保证服务器处理客户端的数据吧! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 做过语音通讯方面的,没有必要开那么多,CPU的处理能力是相当的强的,开多少线程是最优呢?就要测试了 线程数量是有限的,不能那么做.有兴趣看下iocp模型 每个CPU设置线程数目最大值,开多少线程可以根据你的CPU数目决定--仅供参考 使用异步套接字是一种比较理想的方法,例如可以使用select模型,默认情况,可以处理64个客户端连接。但可以自己修改最大连接数,最大数为1024。如果使用线程的话,上千个客户端会导致系统变慢。以下是服务端的select模型,客户端无需使用select。 USHORT port=9050; SOCKET server=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(server==INVALID_SOCKET) { printf("create socket failed\n"); return; } sockaddr_in serAddr; serAddr.sin_family=AF_INET; serAddr.sin_port=htons(port); serAddr.sin_addr.s_addr=INADDR_ANY; if(bind(server,(sockaddr*)&serAddr,sizeof(serAddr))==SOCKET_ERROR) { printf("bind socket failed\n"); return; } fd_set fSocket; FD_ZERO(&fSocket); FD_SET(server,&fSocket); if(listen(server,5)==SOCKET_ERROR) { printf("can not listen the client connection\n"); return; } while(TRUE) { fd_set fRead=fSocket; if(select(0,&fRead,NULL,NULL,NULL)>0) { for(int i=0;i<(int)fSocket.fd_count;++i) { for (int j=0;j<(int)fRead.fd_count;++j) { if(fSocket.fd_array[i]==fRead.fd_array[j]) { if(fRead.fd_array[j]==server) { if(fSocket.fd_count<FD_SETSIZE) { sockaddr_in cltAddr; int addrLen=sizeof(cltAddr); SOCKET client=accept(server,(sockaddr*)&cltAddr,&addrLen); FD_SET(client,&fSocket); printf("接受到一个连接请求:%s:%d\n",inet_ntoa(cltAddr.sin_addr),ntohs(cltAddr.sin_port)); } else { printf("connection is full\n"); continue; } } else { char mess[1024]; memset(mess,0,1024); int messLen=1024; if(recv(fRead.fd_array[j],mess,messLen,0)>0) { printf("接受到数据:%s\n",mess); } else { closesocket(fRead.fd_array[j]); FD_CLR(fSocket.fd_array[i],&fSocket); } } } } } } else { printf("failed select\n"); break; } } closesocket(server);如果要想修改客户端的最大连接数,必须在#include "winsock2.h"之前使用宏来修改FD_SETSIZE的值。 求一个视频播放器的代码 请问这是函数的什么写法?以前没见过 this.SwapBuffer(); 几个界面设计的问题 帮忙推荐两本书吧!有关VC的. 刚起步 如何获得窗口标题栏中最大化和最小化按钮的坐标位置? 奇怪的很!!! cin的问题,如何输入动态字符数组 关于在按钮上显示TOOLTIP 我想让控制台程序跑消息循环,需要创建一个隐藏的HWND吗? html资源传值给mfc框架 vc++ 6.0出错信息处理
CPU的处理能力是相当的强的,
开多少线程是最优呢?就要测试了
--仅供参考
以下是服务端的select模型,客户端无需使用select。
USHORT port=9050;
SOCKET server=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(server==INVALID_SOCKET)
{
printf("create socket failed\n");
return;
}
sockaddr_in serAddr;
serAddr.sin_family=AF_INET;
serAddr.sin_port=htons(port);
serAddr.sin_addr.s_addr=INADDR_ANY;
if(bind(server,(sockaddr*)&serAddr,sizeof(serAddr))==SOCKET_ERROR)
{
printf("bind socket failed\n");
return;
}
fd_set fSocket;
FD_ZERO(&fSocket);
FD_SET(server,&fSocket);
if(listen(server,5)==SOCKET_ERROR)
{
printf("can not listen the client connection\n");
return;
} while(TRUE)
{
fd_set fRead=fSocket;
if(select(0,&fRead,NULL,NULL,NULL)>0)
{
for(int i=0;i<(int)fSocket.fd_count;++i)
{
for (int j=0;j<(int)fRead.fd_count;++j)
{
if(fSocket.fd_array[i]==fRead.fd_array[j])
{
if(fRead.fd_array[j]==server)
{
if(fSocket.fd_count<FD_SETSIZE)
{
sockaddr_in cltAddr;
int addrLen=sizeof(cltAddr);
SOCKET client=accept(server,(sockaddr*)&cltAddr,&addrLen);
FD_SET(client,&fSocket);
printf("接受到一个连接请求:%s:%d\n",inet_ntoa(cltAddr.sin_addr),ntohs(cltAddr.sin_port)); }
else
{
printf("connection is full\n");
continue;
}
}
else
{
char mess[1024];
memset(mess,0,1024);
int messLen=1024;
if(recv(fRead.fd_array[j],mess,messLen,0)>0)
{
printf("接受到数据:%s\n",mess);
}
else
{
closesocket(fRead.fd_array[j]);
FD_CLR(fSocket.fd_array[i],&fSocket); }
}
}
}
}
}
else
{
printf("failed select\n");
break;
}
}
closesocket(server);
如果要想修改客户端的最大连接数,必须在#include "winsock2.h"之前使用宏来修改FD_SETSIZE的值。