• 注册
当前位置:1313e > 默认分类 >正文

I/O模型

如果要实现多个socket同时工作的话,

一 . 同步阻塞 + 多线程

二 . 同步非阻塞(ioctrlsocket):通俗讲,就是每个套接字都去内核看看收没收到消息,没收到再返回

三 . I/O模型select:

      ①集合              fd_set

      ②清空集合            FD_ZERO

      ③将Socket放入集合内       FD_SET

      ④将集合交给select管理       select()

      ⑤校验数据(谁在集合中即收到数据)FD_ISSET

优点:轮循查看集合内socket是否发生网络事件,将发生网络事件的socket留在集合内,简单方便跨平台

缺点:有个数限制(最多处理64个,在winsock2.h定义的宏,我们可以重定义,但最多不超过1024),仍然为阻塞函数(查看,拷回数据)

示例:

bool UDPINet::SelectMySocket(SOCKET sock)
{timeval tm;tm.tv_usec = 100;fd_set fd_sets;FD_ZERO(&fd_sets);FD_SET(sock,&fd_sets);select(NULL,&fd_sets,NULL,NULL,&tm);if(!FD_ISSET(sock,&fd_sets))//列表中没有套接字,则没收到消息,falsereturn false;return true;
}

select函数的参数:

四 . 异步选择(消息):当socket发生事件时发消息

         ①加载库

         ②socket

         ③bind

         ④创建窗口,注册(socket,事件,消息)WSAAsyncSelect()

优点:阻塞时间短,只有拷贝数据时阻塞

缺点:平台限制,只适用于Windows(因为它基于消息),时间消耗多(基于消息)

示例:

    MyWnd = MyWnd->GetWnd();//创建窗口if(!MyWnd->Create(NULL,"MyWnd")){UnInitInet();return false;}//注册WSAAsyncSelect(sock,*MyWnd,NM_MESSAGE,FD_READ);

WSAAsyncSelect()的参数:

其中MyWnd为新创建的窗口,用来接收NM_MESSAGE消息

其中采用单例模型:懒汉模式:单线程

         饿汉模式:多线程

 五 . 异步事件(内核对象,操作系统通知)

与异步消息不同:当socket发生事件时发事件

单个socket情况:

    ws = WSACreateEvent();WSAEventSelect(sock,ws,FD_READ);

线程实现函数:

   if(WAIT_TIMEOUT  == WaitForSingleObject(pthis->ws,100))continue;ResetEvent(pthis->ws);

多个socket情况:将socket和event放入数组,下标相同则对应。

    WSAEVENT ws = WSACreateEvent();if(!WSAEventSelect(sock,ws,FD_READ))//成功返回零
    {aryevent[m_EvetNum] = ws;arysocket[m_EvetNum] = sock;m_EvetNum++;}thread = (HANDLE )_beginthreadex(NULL,0,&UDPINet::ThreadProc,this,0,0);

线程函数:

        WSANETWORKEVENTS ws_network;DWORD  dwResult = WSAWaitForMultipleEvents(pthis->m_EvetNum,pthis->aryevent,FALSE,100,TRUE);if(WAIT_TIMEOUT == dwResult){continue;}dwResult -= WSA_WAIT_EVENT_0 ;//获取事件索引//发生了什么类型的网络事件,成功返回0if(WSAEnumNetworkEvents(pthis->arysocket[dwResult],pthis->aryevent[dwResult],&ws_network))continue;if(ws_network.lNetworkEvents & FD_READ)//得到事件为可读消息
        {nRes = recvfrom(pthis->sock,buf,MAX_SIZE,0,(sockaddr*)&addr,&len);//调用处理函数if(nRes > 0){pthis->m_pIMeditor->DealMessage(buf,addr.sin_addr.S_un.S_addr);}}

 

转载于:https://www.cnblogs.com/Lune-Qiu/p/8610148.html

本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 162202241@qq.com 举报,一经查实,本站将立刻删除。

最新评论

欢迎您发表评论:

请登录之后再进行评论

登录