看流星社区

 找回密码
 注册账号
查看: 1977|回复: 0

I/O模型之select模型

[复制链接]

该用户从未签到

发表于 2017-6-2 11:07:46 | 显示全部楼层 |阅读模式
代码:
void main()
{
        CInitSock initSock;
        USHORT nPort = 9999; //监听的端口
        SOCKET sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (sListen == INVALID_SOCKET)
        {
                printf("socket error...");
                return;
        }
        sockaddr_in servAddr = {0};
        servAddr.sin_family = AF_INET;
        servAddr.sin_port = ::htons(nPort);
        servAddr.sin_addr.S_un.S_addr = INADDR_ANY;
        if (SOCKET_ERROR == ::bind(sListen, (sockaddr*)&servAddr, sizeof(servAddr)))
        {
                int nError = ::GetLastError();
                printf("connect error..");
                return;
        }
        ::listen(sListen, 5);

       
        //select模型处理过程
        //1.初始化套接字集合,添加监听socket到这个集合
        fd_set        fdSocket;
        FD_ZERO(&fdSocket);
        FD_SET(sListen, &fdSocket);
        while (TRUE)
        {
                //2. 将集合的一个拷贝传递给select函数
                //当有事件发生时,select移除未决的socket,然后返回   就是说select返回时 集合的中socket就是发生事件的socket
                fd_set fdRead = fdSocket;
                int nRet = ::select(0, &fdRead, NULL, NULL, NULL);
                if (nRet > 0)
                {
                        //通过比较原来的fdSocket集合与经过处理的fdRead集合
                        for (UINT i=0;i<fdSocket.fd_count;i++)
                        {
                                if (FD_ISSET(fdSocket.fd_array[i], &amp;fdRead)) //就是这个触发了
                                {
                                        if (fdSocket.fd_array[i] == sListen) //监听套接字接收到新连接  为神马分两种情况:因为触发Read集合的情况有两种:有连接来了或数据可读了....
                                        {
                                                //
                                                if (fdSocket.fd_count < FD_SETSIZE) //FD_SETSIZE=64
                                                {
                                                        sockaddr_in addrRemote = {0};
                                                        int nAddrLen = sizeof(addrRemote);
                                                        SOCKET sNew = ::accept(sListen, (sockaddr*)&amp;addrRemote, &amp;nAddrLen);
                                                        FD_SET(sNew, &amp;fdSocket);
                                                }
                                                else       
                                                {
                                                        printf("too many connection...error");
                                                        continue;
                                                }
                                        }
                                        else  //有可读的
                                        {
                                                char szContent[256]={0};
                                                int nRecv = ::recv(fdSocket.fd_array[i], szContent, sizeof(szContent), 0);
                                                if (nRecv > 0)
                                                {
                                                        szContent[nRecv] = '\0';
                                                        printf("recv data:%s", szContent);
                                                }
                                                else //没读到数据
                                                {
                                                        ::closesocket(fdSocket.fd_array[i]);
                                                        FD_CLR(fdSocket.fd_array[i], &amp;fdSocket);
                                                }
                                        }
                                }
                        }
                }
                else
                {
                        printf("nRet litter 0, error...");
                        return;
                }
        }
        ::closesocket(sListen); //与socket配对写
        printf("*******************************");
        getchar();
}



效果图:
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-19 10:38

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表