找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 4478|回复: 1

多进程间通信ACE_Process_Options的pass_handle问题

[复制链接]
发表于 2009-11-18 00:06:57 | 显示全部楼层 |阅读模式
我想在一个主进程(runMaster)中接收来自客户端的链接,然后启动一个子进程(runWork)来处理这个链接。下面的代码中出现了两个问题,请哪位大侠帮忙解决,谢谢:
1、MsgProcess类中的int prepare( ACE_Process_Options &options )函数,调用了ACE_Process_Options的pass_handle函数,调用结果正确,传递的结果也正确。但是在子进程中的int runWork( int argc, char *argv[] )函数下ACE_DEBUG处打印出来的信息和主进程ACE_DEBUG处打印出来的信息不一致。子进程下打印出来的端口号为“0”。
2、void handleData( ACE_SOCK_Stream &peer )中接收不到来自客户端的消息报。

请问,该如何解决,谢谢。

#include "ace\Process.h"
#include "ace\Log_Msg.h"
#include "ace\OS.h"
#include "ace\SOCK_Stream.h"
#include "ace\Acceptor.h"
#include "ace\Process_Manager.h"
#include "ace\SOCK_Acceptor.h"
#include <iostream>
#define PORTNO   10000
#define BUF_SIZE 1024
void handleData( ACE_SOCK_Stream &peer )
{
    ACE_DEBUG((LM_DEBUG, "Beginning to receive data\n"));
    ACE_INET_Addr remoteAddr;
    peer.get_remote_addr(remoteAddr);
    char *buf = new char[BUF_SIZE];

    while ( 1 )
    {
         peer.disable(ACE_NONBLOCK);
         int n = peer.recv( buf, 1024);
         if ( n < 0 )
         {
               std::cout<<remoteAddr.get_host_name() << ":" << remoteAddr.get_port_number() <<std::endl;
               break;
         }
         else
         {
              buf[n] = 0;
              std::cout<< "[%P]Thread receive data [ "<< buf << " ] from "<< remoteAddr.get_host_name() << ":" << remoteAddr.get_port_number() <<std::endl;
              break;
         }
     }
}


class MsgProcess : public ACE_Process
{
public:
     MsgProcess( const char *programName, ACE_SOCK_Stream &msgPeer )
          :msgPeer_(msgPeer.get_handle())
     {
         ACE_OS::strcpy( programName_, programName );
     }

    virtual int prepare( ACE_Process_Options &options )
    {
         if ( options.pass_handle( msgPeer_.get_handle() ) == -1 )
         {
              ACE_DEBUG((LM_DEBUG, "[%P] Pass handle failed\n"));
         }

         options.command_line("%s", programName_);
         options.avoid_zombies(1);
         options.creation_flags(ACE_Process_Options::NO_EXEC);
         return 0;
    }

    virtual void unmanage( void )
    {
        delete this;
    }

private:
    MsgProcess()
    {
    }

private:
    char programName_[MAXPATHLEN + 1];
    ACE_SOCK_Stream msgPeer_;
};

int runWork( int argc, char *argv[] )
{
    ACE_INET_Addr remoteAddr;
    ACE_HANDLE socketHandle = reinterpret_cast<ACE_HANDLE>(atoi(argv[2]));
    ACE_SOCK_Stream peer( socketHandle );
    peer.get_remote_addr(remoteAddr);
    ACE_DEBUG((LM_DEBUG, "[%P] connect with %s:%d\n", remoteAddr.get_host_name(), remoteAddr.get_port_number() ));
    handleData( peer );
    peer.close();
    return 0;
}

int runMaster( int argc, char *argv[] )
{
    ACE_DEBUG( (LM_DEBUG, "[%P]Main process created\n") );
    ACE_INET_Addr localAddr(PORTNO);
    ACE_SOCK_Stream peer;
    ACE_SOCK_Acceptor acceptor;
    ACE_INET_Addr remoteAddr;
    ACE_Process_Options options;
    if ( acceptor.open( localAddr ) == 1 )
    {
        ACE_DEBUG((LM_DEBUG, "Open acceptor failed\n"));
        return -1;
    }
    else
    {
        ACE_DEBUG((LM_DEBUG, "Listening......\n"));
    }

    while(1)
    {
        if ( acceptor.accept(peer) == -1 )
        {
             ACE_DEBUG((LM_DEBUG, "Open acceptor failed\n"));
             return -1;
        }
        else
        {
             peer.get_remote_addr(remoteAddr);
             ACE_DEBUG( (LM_DEBUG, "Connect established from %s:%d!\n", remoteAddr.get_host_name(), remoteAddr.get_port_number()) );

             MsgProcess *process = new MsgProcess(argv[0], peer);
             pid_t pid = ACE_Process_Manager::instance()->spawn( process, options );
             // 新建进程出错的话,Win32返回-1,而其他有可能返回0
             if ( pid <= 0 )
             {
                 peer.close();
                 acceptor.close();
                 delete process;
                 ACE_DEBUG((LM_DEBUG, "Spawn process failed\n"));
                 return -1;
             }
             else
             {
                 peer.close();
                 ACE_DEBUG((LM_DEBUG, "Spawn process [%d] sucess\n", pid));
             }
        }
    }

    return 0;
}

int main( int argc, char *argv[] )
{
    if ( argc > 2 )
    {
        runWork( argc, argv );
     }
     else
     {
         runMaster( argc, argv );
     }
     return ACE_Process_Manager::instance()->wait();
}

[ 本帖最后由 pengxiqin 于 2009-11-18 00:19 编辑 ]
 楼主| 发表于 2009-11-18 21:45:22 | 显示全部楼层

回复 #1 pengxiqin 的帖子

找到原因了,问题在于ACE_Process_Options的pass_handle传递的是句柄16进制的内存地址。所以不能在runWork函数中用atoi来转变这个地址。而应该把这个16进制的数转化为10进制的,再用。
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-11-22 18:03 , Processed in 0.014219 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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