为什么不在线程里去做select检测呢?尽量简单化结构设计
解决方案 »
- 两个对话框的问题~~
- 视图分割的分割线如何按框架大小相对移动
- MFC 中message routing 与message map的关系
- 毕业设计求救,error C2039: 'End' : is not a member of '_Recordset'
- 如何强制写文件
- MFC中如何在对话框函数中获得单文档视图的DC?
- 请问那里有有关bmp图像格式原理的文章吗?我想了解bmp文件的存储格式。
- 我想知道我文件的大小,请问用那个函数来做
- 为什么不能添加成功呢!
- 用recv()接收服务器发送给我的信息时,我如何知道我要接受的数据有多大??
- 关于 BitBlt 的问题
- 发现一个ffmpeg库的bug,求大神指教
http://download.csdn.net/detail/geoff08zhang/4571358
线程池只有10个,可能有100个客户端,在线程池线程里要怎么样select呢?
#define MSGSIZE 1024
int g_iTotalConn = 0;
SOCKET g_CliSocketArr[FD_SETSIZE];int main()
{
WSAStartup(0x0202, &wsaData); // 创建监听socket
sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // 绑定
local.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
local.sin_family = AF_INET;
local.sin_port = htons(PORT);
bind(sListen, (struct sockaddr *)&local, sizeof(SOCKADDR_IN)); // 监听
listen(sListen, 3); // 创建工作者线程
CreateThread(NULL, 0, WorkerThread, NULL, 0, &dwThreadId); while (TRUE)
{
// 接受一个连接
sClient = accept(sListen, (struct sockaddr *)&client, &iaddrSize); // 记录增加的套机子
g_CliSocketArr[g_iTotalConn++] = sClient;
}
return 0;
}DWORD WINAPI WorkerThread(LPVOID lpParam)
{
int i;
fd_set fdread;
int ret;
struct timeval tv = {1, 0};
char szMessage[MSGSIZE]; while (TRUE)
{
FD_ZERO( &fdread ); //清空结构体 for (i = 0; i < g_iTotalConn; i++)
{
FD_SET( g_CliSocketArr[i], &fdread ); //往结构体里增加套接字
} //The select function returns the number of sockets meeting the conditions.
ret = select( NULL, &fdread, NULL, NULL, &tv ); if ( ret == -1 )
{
// 没有任何连接
::Sleep(100);
continue;
}
if ( ret == 0 )
{
// 超时
continue;
}
for (i = 0; i < g_iTotalConn; i++)
{
//whether a socket is included in a set of socket descriptors.
if ( FD_ISSET( g_CliSocketArr[i], &fdread ) )
{
ret = recv(g_CliSocketArr[i], szMessage, MSGSIZE, 0); if ( ret == 0 ) // 客户端socket关闭了
{
DeleteSocket( g_CliSocketArr[i] );
}
else if ( ret == SOCKET_ERROR )
{
DeleteSocket( g_CliSocketArr[i] );
}
else if ( ret > 0 ) // 从客户端接受到信息了
{
szMessage[ret] = '\0';
send(g_CliSocketArr[i], szMessage, strlen(szMessage), 0);
}
}
}
} return 0;
}void DeleteSocket(SOCKET sock)
{
closesocket( sock ); long i;
for ( i=0; i<g_iTotalConn; i++ )
{
if ( sock == g_CliSocketArr[i] )
{
long j=i;
while ( j<g_iTotalConn-1 )
{
g_CliSocketArr[j] = g_CliSocketArr[j+1];
j++;
}
g_iTotalConn--;
return;
}
}
}
select模型只适合单个线程,这由select函数本身的特性决定了,并且读写操作就该紧随其后。这是正确的使用方式。
如果非要用多个线程去处理,不单效率没有提升,反而会带来其他的麻烦,如同步问题、处理次序问题等。
IOCP就是啊。IOCP中,为了节省线程切换带来的资源消耗,采用LIFO的调度。
有个MVP全球峰会,自己买机票搞签证,Microsoft包5天4夜食宿,我没去啊。
下次有空了当旅游再去吧。
你说的线程池无非就是当同时有多少个套接字上面有数据到来时就开多少个线程,然后线程函数里面用相应的套接字调用recv函数去拿数据。但即使这样你拿到的数据也仅仅是属于特定的那个套接字的。