winsocket c++ IO复用 之Select

原创 2016年08月29日 15:11:04

Select对于一个I/O端口,两次调用,两次返回,比阻塞I/O并没有什么优越性,关键是能实现同时对多个IO端口进行监听。





#include <winsock.h>
#include <stdio.h>
#define PORT       22000
#define MSGSIZE    1024
#pragma comment(lib, "ws2_32.lib")
int    g_iTotalConn = 0;
SOCKET g_CliSocketArr[FD_SETSIZE];
DWORD WINAPI WorkerThread(LPVOID lpParameter);
int main()
{
WSADATA     wsaData;
SOCKET      sListen, sClient;
SOCKADDR_IN local, client;
int         iaddrSize = sizeof(SOCKADDR_IN);
DWORD       dwThreadId;
// Initialize Windows socket library
WSAStartup(0x0202, &wsaData);
// Create listening socket
sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
// Bind
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
listen(sListen, 3);
// Create worker thread
CreateThread(NULL, 0, WorkerThread, NULL, 0, &dwThreadId); 
while (TRUE)
{
// Accept a connection
sClient = accept(sListen, (struct sockaddr *)&client, &iaddrSize);
printf("Accepted client:%s:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
// Add socket to g_CliSocketArr
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);
}
// We only care read event
ret = select(0, &fdread, NULL, NULL, &tv);
if (ret == 0)
{
// Time expired
continue;
}
for (i = 0; i < g_iTotalConn; i++)
{
if (FD_ISSET(g_CliSocketArr[i], &fdread))
{
// A read event happened on g_CliSocketArr
ret = recv(g_CliSocketArr[i], szMessage, MSGSIZE, 0);
if (ret == 0 || (ret == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET))
{
// Client socket closed
printf("Client socket %d closed.\n", g_CliSocketArr);
closesocket(g_CliSocketArr[i]);
if (i < g_iTotalConn - 1)
{           
g_CliSocketArr[i--] = g_CliSocketArr[--g_iTotalConn];
}
}
else
{
// We received a message from client
szMessage[ret] = '\0';
send(g_CliSocketArr[i], szMessage, strlen(szMessage), 0);
}
}
}
}


return 0;
}


需要关注的是Select模型 

 FD_ZERO(&set);//将你的套节字集合清空 
 FD_SET(s,   &set);//加入你感兴趣的套节字到集合,这里是一个读数据的套节字s 
 select(0,&set,NULL,NULL,NULL);//检查套节字是否可读, 
                                                      //很多情况下就是是否有数据(注意,只是说很多情况) 
                                                      //这里select是否出错没有写 
    if(FD_ISSET(s,   &set)   //检查s是否在这个集合里面, 
    {                                           //select将更新这个集合,把其中不可读的套节字去掉 
                                                //只保留符合条件的套节字在这个集合里面 
                                
            recv(s,...); 
    
    } 




版权声明:本文为博主原创文章,未经博主允许不得转载。

IO多路复用之select函数详解

IO复用   我们首先来看看服务器编程的模型,客户端发来的请求服务端会产生一个进程来对其进行服务,每当来一个客户请求就产生一个进程来服务,然而进程不可能无限制的产生,因此为了解决大量客户端访问的问题...
  • lixungogogo
  • lixungogogo
  • 2016年08月17日 00:48
  • 2826

使用select实现网络的多路IO复用

说明:只供学习交流,转载请注明出处   使用套接字实现通信的实例中,服务器端在调用recv函数或recvfrom函数接收客户端发送来的消息或在调用accept函数时,都将处于阻塞状态。当进程处于阻...
  • tanghui19900420
  • tanghui19900420
  • 2013年06月02日 17:02
  • 1528

【Socket编程】篇六之IO多路复用——select、poll、epoll

文章参考自:http://blog.csdn.net/tennysonsky/article/details/45745887(秋叶原 — Mike VS 麦克《Linux系统编程——I/O多路复用s...
  • woxiaohahaa
  • woxiaohahaa
  • 2016年06月12日 22:02
  • 3931

Linux系统IO复用接口(select、poll、epoll)

epoll仅仅是一个异步事件的通知机制,其本身并不作任何的IO读写操作,它只负责告诉你是不是可以读或可以写了,而具体的读写操作,还要应用程序自己来完成。epoll仅提供这种机制是非常好的,它保持了事件...
  • yangwen123
  • yangwen123
  • 2013年11月04日 09:14
  • 4484

三种多路复用IO实现方式:select,poll,epoll的区别

select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但select...
  • LookAtTheStars
  • LookAtTheStars
  • 2016年08月03日 23:46
  • 2345

io多路复用之select,poll,epoll总结

点击打开链接
  • me4weizhen
  • me4weizhen
  • 2016年08月09日 18:21
  • 577

WinSocket的select函数的用法(windows套接字比较研究)

总体上来说select函数的作用: 确定一个或多个套接口的状态,本函数用于确定一个或多个套接口的状态,对每一个套接口,调用者可查询它的可读性、可写性及错误状态信息,用fd_set结构来表示一组等待检查...
  • rootusers
  • rootusers
  • 2015年02月07日 17:08
  • 1833

winsocket异步模型--select模式介绍

winsocket创建的套接字默认都是阻塞的,阻塞的意思其实很简单,就是不到黄河不死心的工作方式,譬如我们现在要从这个socket recv数据,如果这个时候没有数据可读或者不可读,那它就会等在那,r...
  • lizheng308
  • lizheng308
  • 2014年07月02日 10:38
  • 1894

Linux-(C)IO多路复用之select学习(转载)

void FD_ZERO(fd_set *fdset); //清空集合 void FD_SET(int fd, fd_set *fdset); //将一个...
  • qq_33850438
  • qq_33850438
  • 2016年07月30日 16:49
  • 377

Linux下的TCP/IP编程----IO复用及IO复用服务端

在之前我们实现的并发服务端时通过床将多个进程来实现的,这种并实现并发的方式简单方便,但是进程的创建和销毁是很消耗系统资源的,在访问量大时服务器很容易出现资源不够用的情况。除此之外,由于每个进程有独立的...
  • wqc_CSDN
  • wqc_CSDN
  • 2016年06月04日 19:07
  • 3267
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:winsocket c++ IO复用 之Select
举报原因:
原因补充:

(最多只允许输入30个字)