ACE_Reactor::register_handler 调用 WSAEventSelect 系统函数, WSAEventSelect 函数自动把关联的 socket 设置为非阻塞模式。

23 篇文章 1 订阅

ACE_Reactor::register_handler 调用 WSAEventSelect 系统函数, 而 WSAEventSelect 函数自动把关联的 socket 设置为非阻塞模式。

看 MSDN 里的描述:
The WSAEventSelect function automatically sets socket s to nonblocking mode, regardless of the value of lNetworkEvents. To set socket s back to blocking mode, it is first necessary to clear the event record associated with socket s via a call to WSAEventSelect with lNetworkEvents set to zero and the hEventObject parameter set to NULL. You can then call ioctlsocket or WSAIoctl to set the socket back to blocking mode.


以代码为例:

#include "ace/Reactor.h"
#include "ace/SOCK_Connector.h"

#include <string>
#include <iostream>
using namespace std;


class CClient:public ACE_Event_Handler 
{
public:
    bool open()
    {
        ACE_SOCK_Connector connector;
        ACE_INET_Addr addr(3000,"127.0.0.1");
        ACE_Time_Value timeout(5,0);
        if(connector.connect(peer,addr,&timeout) != 0)
        {
            cout<<endl<<"connect fail.";
            return false;
        }
        ACE_Reactor::instance()->register_handler(this,ACE_Event_Handler::READ_MASK); // 调用了register_handler函数,
        cout<<endl<<"connected."<<endl;
		
		int i;
		for(i=0; i<300; i++)
		{
			 // 因为前面调用了 register_handler 函数,所以这个 send 是非阻塞模式发送数据的。
			int  n = peer.send(buf,sizeof(buf)); 
			printf("peer.send , i = %d, n = %d\n", i, n);
			if(n<=0)
				printf("peer.send, error = %d\n", errno);
		}

        return true;
    }

	//
	// ACE内部调用get_handle函数,获取socket句柄,ACE_Reactor::register_handler 函数
	// 里的 WSAEventSelect 把这个句柄自动设置为非阻塞模式。

    ACE_HANDLE get_handle(void) const  
    {
        return peer.get_handle();  
    }

    int handle_input (ACE_HANDLE fd)
    {
        return 0;
    }

private:
    ACE_SOCK_Stream peer;
    char buf[1024];
};

int main(int argc, char *argv[]) 
{
    CClient client;
    client.open();

    while(true)
    {
        ACE_Reactor::instance()->handle_events(); 
    }

    return 0; 
}

如果不实现 get_handle 函数,倒可以躲开 WSAEventSelect 函数的设置,peer.send 也保持了阻塞模式。但如果这样做了,CClient 能加入Reactor么?应该不能,没验证。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值