pengxiqin 发表于 2009-11-18 00:06:57

多进程间通信ACE_Process_Options的pass_handle问题

我想在一个主进程(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;

    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 = 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_;
    ACE_SOCK_Stream msgPeer_;
};

int runWork( int argc, char *argv[] )
{
    ACE_INET_Addr remoteAddr;
    ACE_HANDLE socketHandle = reinterpret_cast<ACE_HANDLE>(atoi(argv));
    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, 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 编辑 ]

pengxiqin 发表于 2009-11-18 21:45:22

回复 #1 pengxiqin 的帖子

找到原因了,问题在于ACE_Process_Options的pass_handle传递的是句柄16进制的内存地址。所以不能在runWork函数中用atoi来转变这个地址。而应该把这个16进制的数转化为10进制的,再用。
页: [1]
查看完整版本: 多进程间通信ACE_Process_Options的pass_handle问题