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,...); 
    
    } 




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

相关文章推荐

select IO复用机制

1 基本原理 注:select 原理图,摘自 IBM iSeries 信息中心。 1 数据结构与函数原型 1.1 select 函数原型 int sel...

select多路IO复用服务器

Linux selectIO复用server

IO复用之select poll epoll的总结

I/O复用使得程序能够同时监听多个文件描述符,对于提高程序性能至关重要。I/O复用不仅仅在网络程序中使用,但是我接触到的例子中,TCP网络编程那块使用I/O复用比较多,例如,TCP服务器同时处理监听s...

Linux中select IO复用机制

函数作用: 系统提供select函数来实现多路复用输入/输出模型。select系统调用是用来让我们的程序监视多个文件句柄的状态变化的。程序会停在select这里等待,直到被监视的文件句柄有一个或多个发...

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

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

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

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

网络编程 并发执行 线程 进程 IO复用 select poll

1.    //并发服务器 创建线程负责数据交互 #include #include #include #include #include #include #include #incl...

select、poll、epoll三组IO复用

int select(int nfds,fd_set* readfds,fd_set* writefds,fd_set* exceptfds,struct timeval* timeout)//其中n...

io复用select pselect

linux系统对于多路i/o转接提供了几个强大的函数,但是这些函数各有优缺点,参照网上的资料以及自己的测试,总结如下: 首先看一个程序的例子: #include        #inc...

IO复用: select 和poll 到epoll

linux 提供了select、poll和epoll三种接口来实现多路IO复用。下面总结下这三种接口。 select 该函数允许进程指示内核等待多个事件中的任何一个发生,并只在有一个或多个事件发生或经...
  • fox1987
  • fox1987
  • 2013年09月10日 18:30
  • 722
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:winsocket c++ IO复用 之Select
举报原因:
原因补充:

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