SOCKET clientsockarray[FD_SETSIZE - 1];
char g_buf[1024];BOOL InsertSock(SOCKET* pSock, SOCKET sock);
DWORD WINAPI WorkerThread(LPVOID lpParam);int main(int argc, char* argv[])
{
WSADATA wsaData;
SOCKADDR_IN local;
int iaddrSize = sizeof(SOCKADDR_IN);
DWORD dwThreadId;
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(4096);
bind(sListen, (sockaddr*)&local, sizeof(SOCKADDR_IN));
listen(sListen, 64);
HANDLE hHandle = CreateThread(NULL, 0, WorkerThread, (LPVOID)&sListen, 0, &dwThreadId);
if (NULL != hHandle)
{
printf("Create Thread Successed\n");
CloseHandle(hHandle);
}
else
{
printf("Create Thread Failed!");
}
getchar();
return 0;
}DWORD WINAPI WorkerThread(LPVOID lpParam)
{
printf("ok\n");
SOCKET listensock = *(SOCKET*)lpParam;
SOCKET clientsock;
int nRet = 0;
fd_set fdread;
FD_ZERO(&fdread);
u_long lFlag = 1;
nRet = ioctlsocket(listensock, FIONBIO, &lFlag);
FD_SET(listensock, &fdread);
for (;;)
{
nRet = select(0, &fdread, NULL, NULL, NULL);
if (FD_ISSET(listensock, &fdread))
{
clientsock = accept(listensock, NULL, NULL);
if (!InsertSock(clientsockarray, clientsock))
{
printf("客户端超过了63个,此次连接被拒绝.\n");
closesocket(clientsock);
continue;
}
}
for (int nIndex = 0; nIndex < FD_SETSIZE - 1; nIndex++)
{
if (FD_ISSET(clientsockarray[nIndex], &fdread))
{
nRet = recv(clientsockarray[nIndex], g_buf, sizeof(g_buf), 0);
if (nRet == 0 || nRet == SOCKET_ERROR)
{
closesocket(clientsockarray[nIndex]);
clientsockarray[nIndex] = INVALID_SOCKET;
continue;
}
printf("%s\n", g_buf);
}
}
FD_ZERO(&fdread);
FD_SET(listensock, &fdread);
for (nIndex = 0; nIndex < FD_SETSIZE - 1; nIndex++)
{
if (clientsockarray[nIndex] != INVALID_SOCKET)
FD_SET(clientsockarray[nIndex], &fdread);
}
}
}
BOOL InsertSock(SOCKET* pSock, SOCKET sock)
{
for (int nIndex = 0; nIndex < FD_SETSIZE - 1; nIndex++)
{
if(pSock[nIndex] == INVALID_SOCKET)
{
pSock[nIndex] = sock;
break;
}
}
if (nIndex == FD_SETSIZE - 1)
return FALSE;
return TRUE;
}
有几个问题不清楚,希望大家谈谈:
1,在WorkerThread(LPVOID lpParam)线程中是否最多同时有64个客户可以accept成功,不是同时可以接收无限个客户
2,在WorkerThread(LPVOID lpParam)线程中,发现accept连接不成功,可不可以断定同一时刻这个客户是第大于64的客户
3,我发现accept连接不成功,可以在那里再开一个线程吗,一般的服务器怎么处理并发多个客户的?
解决方案 »
- 多文档替换背景位图?
- 怎样在窗体上的CStatic 上面画图?
- Slider Control的点击与拖动问题
- 基础问题求解。关于如何在原有程序上加入静态链接库。解决马上结分
- 各位大哥,大姐们,上面的那问题(高分求一简单程序...)也没什么难度吧,怎么没人回呢???
- 怎样才能在dialogbox 中使用主窗口里定义的对象?
- “行”还是“不行”?!如何用ODBC来压缩ACCESS97数据库?
- 关于远程dll注入和hook的问题
- 大虾:哪有手机铃音的格式?
- 模拟网页操作,遇到alert弹窗
- 一个简单的抽屉程序,类定义出现的问题,大家帮帮忙!!
- 怎么每次在打开一个盘符的时候,让它必须先自动运行我自己的窗口
// Select.cpp : Defines the entry point for the console application.
//#include "stdafx.h"
#include <stdio.h>
#include <InitSock.h>CInitSock theSock;
int main(int argc, char* argv[])
{
USHORT nPort=4567;
//创建监听套接字
SOCKET sListen=::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(nPort);
sin.sin_addr.S_un.S_addr=INADDR_ANY; //绑定套接字到本地机器
if (::bind(sListen,(sockaddr*)&sin,sizeof(sin))==SOCKET_ERROR)
{
printf("failed bind()\n");
return -1;
}
//进入监听模式
::listen(sListen,5); //select模型处理过程
//1. 初始化一个套接字集合fdSocket,添加监听套接字句柄到这个集合 fd_set fdSocket;
FD_ZERO(&fdSocket);
FD_SET(sListen,&fdSocket); while (true)
{
//2) 将fdSocket的一个拷贝fdRead传递给select函数
//当有事件发生时,select函数移出fdRead集合中没有未决io操作的套接字句柄,返回
fd_set fdRead=fdSocket;
int nRet=::select(NULL,&fdRead,NULL,NULL,NULL);
// printf("hello\n");
if (nRet>0)
{
//3)比较fdSocket和fdRead,确定未决io;
for (int i=0;i<(int)fdSocket.fd_count;i++)
{
// printf("%d",(int)fdSocket.fd_count);
if (FD_ISSET(fdSocket.fd_array[i],&fdRead))
{
if (fdSocket.fd_array[i]==sListen)//监听套接字接收新连接
{
if (fdSocket.fd_count<FD_SETSIZE)
{
sockaddr_in addrRemote;
int nAddrLen=sizeof(addrRemote);
SOCKET sNew=::accept(sListen,(sockaddr*)&addrRemote,&nAddrLen);
FD_SET(sNew,&fdSocket);
printf("接收到连接(%s)\n",::inet_ntoa(addrRemote.sin_addr));
}
else
{
printf("too much connections!\n");
continue;
}
}
else
{
char szText[256];
int nRecv=::recv(fdSocket.fd_array[i],szText,strlen(szText),0);
if (nRecv>0)//可读
{
szText[nRecv]='\0';
printf("接收到数据:%s",szText); }
else //关闭连接,重启,中断
{
::closesocket(fdSocket.fd_array[i]);
FD_CLR(fdSocket.fd_array[i],&fdSocket);
}
}
}
}
}
else
{
printf("failed select()!\n");
break;
}
}
return 0;
}
u_long lFlag = 1;
nRet = ioctlsocket(listensock, FIONBIO, &lFlag);
用了阻塞的方式,
而在:
int nRet=::select(NULL,&fdRead,NULL,NULL,NULL);
却用了非阻塞的方式
那不最多有10W,
这样做可以么?
同时能支持多少个连接?我想这主要是受系统资源限制吧,不知道tcp协议栈软件有没有这种连接数量的限制
listen()
while(1)
{
select()
newsocket=accept();
_beginthreadex(处理newsocket); //这里怎么管理这些线程,就是你所说的线程池了
//接着select,等待新的连接
}
2, accept失败时返回值为INVALID_SOCKET;一般可以丢弃这个连接。