请问handle_output怎么不能使用
#pragma comment(lib, "ACED.lib")//利用的是reactor的acceptor-connector模式,在标准的reactor模式下亦如此。
//现象是第一次调用handle_output后没有问题,第二次调用时就不能用了,无法调用,不知道怎么回事。
#include "ace/Reactor.h"
#include "ace/Svc_Handler.h"
#include "ace/Connector.h"
#include "ace/Synch.h"
#include "ace/SOCK_Connector.h"
class My_Svc_Handler:
public ACE_Svc_Handler <ACE_SOCK_STREAM,ACE_NULL_SYNCH>
{
public:
int open(void*)
{
printf("Connection established\n");;
//ACE_Reactor::instance()->register_handler(this, ACE_Event_Handler::WRITE_MASK);
ACE_Reactor::instance()->register_handler(this, ACE_Event_Handler::READ_MASK);
return 0;
}
int handle_input(ACE_HANDLE)
{
char data;
int iLen = peer().recv(data, 128);
if (iLen > 0)
{
data = 0;
printf("receved : %s\n", data);
}
strcpy(data, "hello acceptor!");
peer().send(data, strlen(data));
ACE_Reactor::instance()->register_handler(this, ACE_Event_Handler::WRITE_MASK);
return 0;
}
int handle_output(ACE_HANDLE)
{
char *data = "hello acceptor!";
printf("handle_output\n");
peer().send(data, strlen(data));
return -1;
}
int handle_close(ACE_HANDLE, ACE_Reactor_Mask mask)
{
if (mask == ACE_Event_Handler::WRITE_MASK)
{
printf ("WRITE_MASK:handle_close\n");
return 0;
}
}
};
typedef ACE_Connector<My_Svc_Handler,ACE_SOCK_CONNECTOR> MyConnector;
int main(int argc, char* argv[])
{
ACE_INET_Addr addr(1500, "192.168.0.133");
My_Svc_Handler *handler = new My_Svc_Handler;
//instantiate the appropriate acceptor object with the address on which
//we wish to accept and the Reactor instance we want to use. In this
//case we just use the global ACE_Reactor singleton. (Read more about
//the reactor in the previous chapter)
MyConnector connector;
if (connector.connect(handler, addr) == -1)
ACE_ERROR((LM_ERROR, "%P|%t, %p", "Connection failed"));
while(1)
// Start the reactor’s event loop
ACE_Reactor::instance()->handle_events();
}
//下边代码是不停地向其发送消息
// ace_socket1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "ace/INET_Addr.h"
#include "ace/SOCK_Stream.h"
#include "ace/SOCK_Connector.h"
#include "ace/Log_Msg.h"
#include "ace/OS_NS_unistd.h"
#include "ace/Service_Config.h"
int
ACE_TMAIN(int argc,ACE_TCHAR *argv[])
{
if (ACE_Service_Config::open(argc,
argv,
ACE_DEFAULT_LOGGER_KEY,
1,
0,
1) < 0)
{
ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("%p\n"), ACE_TEXT("Service Config open")), -1);
}
ACE_INET_Addr srvr (44444, "192.168.0.133");//ACE_LOCALHOST);
ACE_SOCK_Connector connector;
ACE_SOCK_Stream peer;
ACE_Time_Value timeout(10);
//if (-1 == connector.connect(peer, srvr))
// ACE_ERROR_RETURN ((LM_ERROR,
// ACE_TEXT("%p\n"),
// ACE_TEXT ("connect")),
// 1);
ACE_OS::last_error(0);
if (connector.connect(peer, srvr, &timeout)== -1)
{
if (ACE_OS::last_error() == ETIME)
{
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT("(%p|%t) Timeout while"),
ACE_TEXT ("connecting to log server\n")));
}
else
{
ACE_ERROR((LM_ERROR,
ACE_TEXT("%p\n"),
ACE_TEXT("log")));
}
return 101;
}
int i = ACE_OS::last_error();
printf("error: %d\n", i);
int bc;
char buf;
char *ptr = "hello world!\n";
//i = peer.send_n (ptr, strlen(ptr));
//ACE_OS::sleep(5);
do
{
i = peer.send_n (ptr, strlen(ptr));
if (i>0)
write (1, ptr, i);
//ACE_OS::sleep(2);
//i = peer.send_n (ptr, strlen(ptr));
//if (i>0)
// write (1, ptr, i);
/* bc = peer.recv(buf, sizeof(buf));
if (bc > 0)
write (1, buf, bc);*/
ACE_OS::sleep(2);
}while(1);
peer.close();
//getchar();
return 0;
}
请问这是咋回事?? 在网上找了资料说更换反应器ACE_TP_Reactor就可以了,原因如下:Windows默认的反应器是ACE_WFMO_Reactor,它采用的是“边缘触发”方式,即内部使用的是 WaitForMultipleObjects(),只有状态变化(不可写变为可写)时才会被触发,所以在调用一次handle_ouput()后,由于状态一直可写,所以该函数不会再调用。有人也许会问,那为什么handle_input()为什么能一直被调用呢?那是因为你调用了recv()函数,该函数会使状态复位,所以只要是可读的时候handle_input()就会被调用。而ACE_TP_Reactor采用的是"水平触发"方式,即内部使用的是select()函数,只要是可写的,它就调用handle_output()。
ACE_TP_Reactor *tp_reactor = new ACE_TP_Reactor;
ACE_Reactor *my_reactor = new ACE_Reactor(tp_reactor, 1);
ACE_Reactor::instance(my_reactor, 1);
页:
[1]