之一 select模型

// select.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#pragma comment(lib,"ws2_32.lib")

int _tmain(int argc, _TCHAR* argv[])
{
    WORD wVersion = MAKEWORD(2,2);
    WSADATA wsaData = {0};
    if(WSAStartup(wVersion,&wsaData)!=0)
    {
        printf("Inin WSAStartup Error\r\n");
        return -1;
    }

    SOCKET ListenSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(ListenSocket==INVALID_SOCKET)
    {
        WSACleanup();
        printf("Create Socket Error\r\n");
        return -1;
    }
    sockaddr_in LocalAddress;
    LocalAddress.sin_family = AF_INET;
    LocalAddress.sin_port = htons(9627);
    LocalAddress.sin_addr.S_un.S_addr = INADDR_ANY;

    if(bind(ListenSocket,(sockaddr*)&LocalAddress,sizeof(LocalAddress))==SOCKET_ERROR)
    {
        closesocket(ListenSocket);
        WSACleanup();
        printf("Failed bind()\r\n");
        return -1;
    }
    listen(ListenSocket,5);

    fd_set fdSocket;
    FD_ZERO(&fdSocket);
    FD_SET(ListenSocket,&fdSocket);
    while(true)
    {
        fd_set fdRead = fdSocket;
        int iPending = select(0,&fdRead,NULL,NULL,NULL);
        if(iPending>0)
        {
            for(int i=0;i<(int)fdSocket.fd_count;i++)
            {
                if(FD_ISSET(fdSocket.fd_array[i],&fdRead))
                {
                    if(fdSocket.fd_array[i]==ListenSocket) //什么时候不相等,即能跳到下一个else
                    {
                        if(fdSocket.fd_count<FD_SETSIZE)
                        {
                            sockaddr_in addrRemote;
                            int nAddrLen = sizeof(addrRemote);
                            SOCKET sNew = accept(ListenSocket,(sockaddr*)&addrRemote,&nAddrLen);
                            FD_SET(ListenSocket,&fdSocket);
                            printf("接收到链接:%s\n",inet_ntoa(addrRemote.sin_addr));
                        }
                        else
                        {
                            printf("Too much connections!\n");
                            continue;
                        }
                    }
                    else
                    {
                        char szBufferData[0x1000];
                        int iReturn = recv(fdSocket.fd_array[i],szBufferData,0x1000,0);
                        if(iReturn > 0)
                        {
                            szBufferData[iReturn] = ‘\0‘;
                            printf("接受信息:%s\n", szBufferData);
                        }
                        else
                        {
                            closesocket(fdSocket.fd_array[i]);
                            FD_CLR(fdSocket.fd_array[i],&fdSocket);
                        }
                    }
                }
            }
        }
    }
    return 0;
}
时间: 2024-10-20 11:02:11

之一 select模型的相关文章

socket编程:多路复用之select模型

系统提供select函数来实现多路复用输入/输出模型. select函数让我们的程序监视多个文件描述符的状态变化.程序会停在select这里等待,直到被监视的文件描述符中有一个或多个发生了状态变化 函数原型如下: 返回值:   成功返回就绪描述符的个数,超过timeout时间且没有任何事件发生返回0,失败返回-1 参数解释: nfds:    被监视的文件描述符中值最大描述符值加1(描述符是从0开始的,描述符0.1.2...nfds-1均将被测试) 下面三个参数readset.writeset和

服务器select模型

多路转接I/O服务器中的一种:select服务器,该模型的服务器是将文件描述符放入队列中保存并监听,以轮询的机制去监听这些文件描述符,当相对应的文件描述符有读请求.写情况或异常发生时,对应的位将发生变化.select模型需要对所有监听的套接字实行轮询监听处理,当需要监听的套接字过多时,就可能出现响应不及时等问题,从而降低了服务器性能. 下面是服务器的实现(服务器将客户端发送过来的数据全部转换为大写) #include <stdio.h> #include <fcntl.h> #in

select模型的原理、优点、缺点

关于I/O多路复用: I/O多路复用(又被称为“事件驱动”),首先要理解的是,操作系统为你提供了一个功能,当你的某个socket可读或者可写的时候,它可以给你一 个通知.这样当配合非阻塞的socket使用时,只有当系统通知我哪个描述符可读了,我才去执行read操作,可以保证每次read都能读到有效数据而不 做纯返回-1和EAGAIN的无用功.写操作类似.操作系统的这个功能通过select/poll/epoll之类的系统调用来实现,这些函数都可以同时 监视多个描述符的读写就绪状况,这样,**多个描

Winsock IO模型之select模型

之所以称其为select模型是因为它主要是使用select函数来管理I/O的.这个模型的设计源于UNIX系统,目的是允许那些想要避免在套接字调用上阻塞的应用程序有能力管理多个套接字. int select( int nfds,                                                 // 忽略,仅是为了与Berkeley套接字兼容 fd_set* readfds,                                  // 指向一个套接字集合,

[00015]-[2015-09-04]-[01]-[WinSocket编程1 Select模型开发]

套接字Select模型是比较常用的一种I/O模型,利用该模型使得Windows Sockets应用程序可以在同一时间内管理和控制多个套接字,该模型的核心就是select()函数----调用select()函数检查当前多个套接字的状态----是否可读,可写,有异常.....根据该函数的返回值,判断套接字的可读可写性,然后调用相应的Windows Sockets API函数完成数据的发送和接收等操作.... [阻塞模式] 套接字执行I/O操作时,如果执行操作的条件没有得到满足,线程会被阻塞在该调用的

基于select模型的udp客户端实现超时机制

参考:http://www.cnblogs.com/chenshuyi/p/3539949.html 多路选择I/O — select模型 其思想在于使用一个集合,该集合中包含需要进行读写的fd,通过轮询这个集合,直到有一个fd可读写,才返回.与阻塞I/O不同的是,阻塞I/O仅使用了一次系统调用,就是对fd的读写,如果没有fd处于就绪状态,则进程一直阻塞,而多路选择I/O使用了两次系统调用,第一次是轮询并返回可读写fd数,第二次是对fd进行读写,阻塞只发生在轮询fd的过程. select函数的原

socket select模型

由于socket recv()方法是堵塞式的,当多个客户端连接服务器时,其中一个socket的recv调用时,会产生堵塞,使其他连接不能继续. 如果想改变这种一直等下去的焦急状态,可以多线程来实现(不再等待,同时去recv,同时阻塞),每个socket连接使用一个线程,这样效率十分低下,根本不可能应对负荷较大的情况(是啊,占用各种资源,电脑啊,你耗不起). 这时候我们便可以采取select模型.select允许进程指示内核等待多个事件中的任何一个发生,并仅在有一个或多个事件发生或经历一段指定时间

Select 模型1

Select模型原理 利用select函数,判断套接字上是否存在数据,或者能否向一个套接字写入数据.目的是防止应用程序在套接字处于锁定模式时,调用recv(或send)从没有数据的套接字上接收数据,被迫进入阻塞状态. select参数和返回值意义如下: int select ( IN int nfds,                           //0,无意义 IN OUT fd_set* readfds,      //检查可读性 IN OUT fd_set* writefds,  

socket select()模型

转载:http://www.cnblogs.com/xiangshancuizhu/archive/2012/10/05/2711882.html 由于socket recv()方法是阻塞式的,当有多个客户端连接服务器时,其中一个socket的recv调用产生了阻塞,使其他链接不能继续.如果想改变这种一直等下去的焦急状态,可以多线程来实现(不再等待,同时去recv,同时阻塞),每个socket连接使用一个线程,这样效率十分低下,根本不可能应对负荷较大的情况(是啊,占用各种资源,电脑啊,你耗不起)

比较一下Linux下的Epoll模型和select模型的区别

一. select 模型(apache的常用) 1. 最大并发数限制,因为一个进程所打开的 FD (文件描述符)是有限制的,由 FD_SETSIZE 设置,默认值是 1024/2048 ,因此 Select 模型的最大并发数就被相应限制了.自己改改这个 FD_SETSIZE ?想法虽好,可是先看看下面吧 … 2. 效率问题, select 每次调用都会线性扫描全部的 FD 集合,这样效率就会呈现线性下降,把 FD_SETSIZE 改大的后果就是,大家都慢慢来,什么?都超时了. 3. 内核 / 用