select 非阻塞模式 服务器 代码
来源:互联网 发布:上海银行淘宝金卡年费 编辑:程序博客网 时间:2024/05/21 03:25
// TCP Server select非阻塞模式
// IP: 127.0.0.1
// PORT: 1207
#define LISTEN_IP "127.0.0.1"
#define LISTEN_PORT 1207
#define DEFAULT_BUFF 256
#define MAX_LISTEN 2 //最多可同时连接的客户端数量
int g_fd_ArrayC[MAX_LISTEN] = {0}; //处理所有的待决连接
int _tmain(int argc, _TCHAR* argv[])
{
WSAData wsData;
SOCKET sListen;
SOCKET sClient;
SOCKADDR_IN addrListen;
SOCKADDR_IN addrClient;
int addrClientLen = sizeof(addrClient);
char recvBuff[DEFAULT_BUFF] = {0};
char responseBuff[DEFAULT_BUFF] = {"Server Has Received"};
char noresponseBuff[DEFAULT_BUFF] = {"服务器端连接数已满,无法连接"};
int nRes = 0;
printf(">>>>>TCP 服务器端启动<<<<<<\n");
WSAStartup(MAKEWORD(2,2), &wsData);
printf("-创建一个SOCKET\n");
sListen = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if(sListen==INVALID_SOCKET)
{
printf("!!! socket failed: %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
printf("-设定服务器监听端口\n");
addrListen.sin_family = AF_INET;
addrListen.sin_addr.S_un.S_addr = inet_addr( LISTEN_IP );
addrListen.sin_port = htons( LISTEN_PORT );
printf("-绑定SOCKET与指定监听端口: %s:%d\n", inet_ntoa(addrListen.sin_addr), ntohs(addrListen.sin_port));
nRes = bind( sListen, (const sockaddr*)&addrListen, sizeof(addrListen) );
if( nRes == SOCKET_ERROR )
{
printf("!!! bind failed: %d\n", WSAGetLastError());
closesocket( sListen );
WSACleanup();
return -1;
}
printf("-监听端口\n");
nRes = listen( sListen, MAX_LISTEN );
if( nRes == SOCKET_ERROR )
{
printf("!!! listen failed: %d\n", WSAGetLastError());
closesocket( sListen );
WSACleanup();
return -1;
}
/////////////////////////////
// 非阻塞模式设定
//
/////////////////////////////
DWORD nMode = 1;
nRes = ioctlsocket( sListen, FIONBIO, &nMode );
if( nRes == SOCKET_ERROR )
{
printf("!!! ioctlsocket failed: %d\n", WSAGetLastError());
closesocket( sListen );
WSACleanup();
return -1;
}
printf("-设置服务器端模式: %s\n", nMode==0? "阻塞模式":"非阻塞模式");
printf("-开始准备接受连接\n");
fd_set fdRead;
fd_set fdWrite;
timeval tv={10,0};
int nLoopi = 0;
int nConnNum = 0;
while(true)
{
printf("-select 开始\n");
FD_ZERO(&fdRead, &fdWrite);
FD_SET( sListen, &fdRead );
//将待决的连接SOCKET放入fdRead集中进行select监听
//每次进入循环都要没空,重设
for( nLoopi=0; nLoopi<MAX_LISTEN; ++nLoopi )
{
if( g_fd_ArrayC[nLoopi] !=0 )
{
printf("-LOOPI: 待决SOCKET: %d\n",g_fd_ArrayC[nLoopi] );
FD_SET( g_fd_ArrayC[nLoopi], &fdRead );
}
}
//调用select模式进行监听
nRes = select( 0, &fdRead, NULL, NULL, &tv );
;;;;;if( nRes == 0 )
{
printf("-!!! select timeout: %d sec\n",tv.tv_sec);
continue; //继续监听
}
else if( nRes < 0 )
{
printf("!!! select failed: %d\n", WSAGetLastError());
break;
}
//检查所有的可用SOCKET
printf("-查找可用的SOCKET\n");
for( nLoopi=0; nLoopi<MAX_LISTEN; ++nLoopi )
{
if( FD_ISSET(g_fd_ArrayC[nLoopi], &fdRead) )
{
memset( recvBuff, 0 ,sizeof(recvBuff) );
nRes = recv( g_fd_ArrayC[nLoopi], recvBuff, sizeof(recvBuff)-1, 0 );
if( nRes <= 0 )
{
printf("-Client Has Closed.\n");
closesocket( g_fd_ArrayC[nLoopi] );
//将已经关闭的SOCKET从FD集中删除
FD_CLR( g_fd_ArrayC[nLoopi], &fdRead );
g_fd_ArrayC[nLoopi] = 0;
--nConnNum;
}
else
{
recvBuff[nRes] = '\0';
printf("-Recvied: %s\n", recvBuff);
send( g_fd_ArrayC[nLoopi], responseBuff, strlen(responseBuff), 0 );
}
}
}//for( nLoopi=0; nLoopi<MAX_LISTEN; ++nLoopi )
//检查是否为新的连接进入
if( FD_ISSET( sListen, &fdRead) )
{
printf("-发现一个新的客户连接\n");
sClient = accept( sListen, (sockaddr*)&addrClient, &addrClientLen );
;;;;;if( sClient == WSAEWOULDBLOCK )
{
printf("!!! 非阻塞模式设定 accept调用不正\n");
continue;
}
else if( sClient == INVALID_SOCKET )
{
printf("!!! accept failed: %d\n", WSAGetLastError());
continue;
}
//新的连接可以使用,查看待决处理队列
if( nConnNum<MAX_LISTEN )
{
for(nLoopi=0; nLoopi<MAX_LISTEN; ++nLoopi)
{
if( g_fd_ArrayC[nLoopi] == 0 )
{//添加新的可用连接
g_fd_ArrayC[nLoopi] = sClient;
break;
}
}
++nConnNum;
printf("-新的客户端信息:[%d] %s:%d\n", sClient, inet_ntoa(addrClient.sin_addr), ntohs(addrClient.sin_port));
}
else
{
printf("-服务器端连接数已满: %d\n", sClient);
send( sClient, noresponseBuff, strlen(noresponseBuff), 0 );
closesocket( sClient );
}
}//if( FD_ISSET( sListen, &fdRead) )
}//while(true)
printf("-关闭服务器端SOCKET\n");
closesocket( sListen );
WSACleanup();
return 0;
}
原文转自http://hi.baidu.com/duycllvljladfrr/item/9d0f02d4868d1ed4241f40a2
- select 非阻塞模式 服务器 代码
- select 模式 非阻塞
- windows网络编程之Winsock非阻塞select模式服务器
- select非阻塞模式使用
- windows网络编程之Winsock(三)非阻塞select模式服务器
- windows网络编程之 (三) - Winsock非阻塞select模式服务器
- linux下socket编程 select实现非阻塞模式多台客户端与服务器通信
- linux socket select非阻塞模式多台客户端与服务器通信
- linux 下非阻塞客户端,服务器代码
- web静态服务器-非阻塞模式
- IO阻塞非阻塞. select
- IO阻塞非阻塞. select
- 阻塞 非阻塞 select epoll
- Java服务器 混合阻塞和非阻塞模式例子
- NIO Socket非阻塞模式代码示例
- 非阻塞IO--Select
- Linux下套接字详解(八)----select模式下服务器(非阻塞,单进程+多进程+多线程)
- select 非阻塞 sock服务端客户端代码实例
- 修改控件Spinner内容的字体大小 颜色等属性
- 总结用户控件和注册控件
- C++动态分配数组
- spring 下载地址
- Eclipse快捷键大全
- select 非阻塞模式 服务器 代码
- python list存储的是reference id
- CDatabase::ExecuteSQL()
- Memcache协议中文版
- ASP.NET十分有用的页面间传值方法
- 找不到或无法加载主类 Hello,求高手指点啊
- Linux:ls以K、M、G为单位查看文件大小
- 10046事件
- 编译asp.net 2.0项目到dll文件