IPC

#pragma once

#include "boost/signal.hpp"
#include "define.h"

class IPCHELPER_API INetCommunicate
{
public:
 typedef boost::signal<void (BYTE *buffer, int length)> IPCDataRecive_Signal;
 typedef IPCDataRecive_Signal::slot_type IPCDataRecive_Slot;
 typedef boost::signals::connection IPCDataRecive_Conn;

public:
 INetCommunicate(void) {}
 virtual ~INetCommunicate(void) {}

 virtual int SendData(BYTE *buffer, int length) = 0;
 virtual IPCDataRecive_Conn AddListener(IPCDataRecive_Slot slot) = 0;
 virtual void Stop() = 0;
 virtual BOOL Connected() = 0;
};

 

#pragma once

#include "inetcommunicate.h"

#include "ace/ACE.h"
#include "ace/OS.h"
#include "ace/INET_Addr.h"
#include "ace/Log_Msg.h"
#include "ace/SOCK_Acceptor.h"
#include "ace/SOCK_Stream.h"
#include "boost/thread.hpp"

#define SIZE_BUF (1024 * 1024 * 100)

class TCPServerSingle : public INetCommunicate
{
public:
 TCPServerSingle(int port) : server_addr_(port), peer_acceptor_(server_addr_)
 {
  data_buf_= new BYTE[SIZE_BUF];
  stoped = FALSE;
  
  boost::thread th(boost::bind(&TCPServerSingle::accept_connections, this));
 }

 virtual ~TCPServerSingle(void);

 virtual int SendData(BYTE *buffer, int length);
 virtual IPCDataRecive_Conn AddListener(IPCDataRecive_Slot slot);
 virtual void Stop();
 virtual BOOL Connected() {return !stoped;}

private:
 int handle_connection(); 
 void accept_connections(); 

private:
 IPCDataRecive_Signal signal;

 BYTE *data_buf_;
 ACE_INET_Addr server_addr_;
 ACE_INET_Addr client_addr_;
 ACE_SOCK_Acceptor peer_acceptor_;
 ACE_SOCK_Stream new_stream_;

 BOOL stoped;
};

 

#include "TCPServerSingle.h"
#include "LoggingService.h"
#include "boost/smart_ptr/detail/yield_k.hpp"
#include "boost/lexical_cast.hpp"
#include "tstring.h"

TCPServerSingle::~TCPServerSingle(void)
{
 delete [] data_buf_;
}

void TCPServerSingle::Stop()

 stoped = TRUE;
 boost::detail::Sleep(500);
}

int TCPServerSingle::SendData(BYTE *buffer, int length)
{
 int count = new_stream_.send_n(buffer, length);
 return count;
}

INetCommunicate::IPCDataRecive_Conn TCPServerSingle::AddListener(IPCDataRecive_Slot slot)
{
 return signal.connect(slot);
}

int TCPServerSingle::handle_connection()
{
 // Read data from client
 int msg_size = 0;
 while(1)
 {
  msg_size = 0;
  if(new_stream_.recv_n((BYTE*)&msg_size, 4, 0) == -1)
  {
   boost::detail::Sleep(1);   
  }
  else
  {
   LoggingService::LoggingINFO(_T("server receive data"));
   if (msg_size < 0)
   {
    new_stream_.close();
    break;
   }
   else
   {
    if(new_stream_.recv_n(data_buf_, msg_size, 0) == -1)
    {
     int a = GetLastError();
     LoggingService::LoggingERROR(_T("data package format error"));
    }
    else
    {
     LoggingService::LoggingTRACE(_T("data package received"));
     if (!signal.empty())
     {
      signal(data_buf_, msg_size);
     }
     LoggingService::LoggingTRACE(_T("data package distributed"));
    }
   }
  }
 } 

 return 0;
}

void TCPServerSingle::accept_connections()
{
 LoggingService::InitialSevice();

 timeval t;
 t.tv_sec = 0;
 t.tv_usec = 100;
 ACE_Time_Value timeout(t);

 if (peer_acceptor_.get_local_addr (server_addr_) == -1)
 {
  LoggingService::LoggingERROR(_T("Error in get local_addr")); 
  return;
 }
 else
 {
  LoggingService::LoggingINFO(_T("Get local_addr success"));
 }

 // Performs the iterative server activities.
 int srecvStart, srecvEnd, srecvTime = 0;
 while(!stoped)
 {  
  if (peer_acceptor_.accept (new_stream_, &client_addr_, &timeout)== -1)
  {   
   continue;
  }
  else
  {
   LoggingService::LoggingINFO(_T("A client connected"));
   //ACE_DEBUG((LM_DEBUG, "Connection established with remote %s:%d/n", client_addr_.get_host_name(), client_addr_.get_port_number()));
   srecvStart = GetTickCount();
   handle_connection();
   srecvEnd = GetTickCount();
   srecvTime = srecvEnd - srecvStart;
  }
 }
}

 

#pragma once

#include "inetcommunicate.h"
#include "tstring.h"
#include "define.h"
#include "boost/thread.hpp"

#include "ace/ACE.h"
#include "ace/Log_Msg.h"
#include "ace/SOCK_Connector.h"
#include "ace/INET_Addr.h"
#include "ace/OS.h"

#define SIZE_BUF (1024 * 1024 * 100)

class TCPClientSingle : public INetCommunicate
{
public:
 TCPClientSingle(const char *hostname, int port) : remote_addr_(port, hostname)
 {
  data_buf_ = new BYTE[SIZE_BUF];
  data_buf_send = new BYTE[SIZE_BUF];

  connected = FALSE;
  
  connect_to_server();
  boost::thread th(boost::bind(&TCPClientSingle::read_data, this));
 }

 ~TCPClientSingle(void);

 virtual int SendData(BYTE *buffer, int length);
 virtual IPCDataRecive_Conn AddListener(IPCDataRecive_Slot slot);
 virtual void Stop();
 virtual BOOL Connected() {return connected;}

private: 
 int connect_to_server();
 void read_data();
 int close();

private:
 IPCDataRecive_Signal signal;
 ACE_SOCK_Stream client_stream_;
 ACE_INET_Addr remote_addr_;
 ACE_SOCK_Connector connector_;
 BYTE *data_buf_;
 BYTE *data_buf_send;

 BOOL connected;
};

 

#include "TCPClientSingle.h"
#include "LoggingService.h"
#include "boost/lexical_cast.hpp"
#include "boost/smart_ptr/detail/yield_k.hpp"

TCPClientSingle::~TCPClientSingle(void)
{
 delete [] data_buf_;
 data_buf_ = NULL;
 delete [] data_buf_send;
 data_buf_send = NULL;
}

INetCommunicate::IPCDataRecive_Conn TCPClientSingle::AddListener(IPCDataRecive_Slot slot)
{
 return signal.connect(slot);
}

int TCPClientSingle::connect_to_server()
{
 // Initiate blocking connection with server.
 LoggingService::LoggingINFO(boost::lexical_cast<std::wstring>(remote_addr_.get_host_name()));
 LoggingService::LoggingINFO(boost::lexical_cast<std::wstring>(remote_addr_.get_port_number()));
 
 if (connector_.connect(client_stream_, remote_addr_) == -1)
 {
  connected = FALSE;
  LoggingService::LoggingINFO(_T("connect server failed"));
 }
 else
 {
  connected = TRUE;
  LoggingService::LoggingINFO(_T("connect server success"));
 }

 return 0;
}

int TCPClientSingle::SendData(BYTE *buffer, int length)
{
 if (!connected)
 {
  return 0;
 } 

 memcpy(data_buf_send, (BYTE*)&length, 4);
 memcpy(data_buf_send + 4, buffer, length);

 int count = 0; 

 LoggingService::LoggingINFO(_T("Client sending data"));
 count = client_stream_.send_n(data_buf_send, length + 4, 0);
 LoggingService::LoggingINFO(_T("Client sent data"));

 return count;
}

int TCPClientSingle::close()

 if (client_stream_.close () == -1)
 {
  LoggingService::LoggingERROR(_T("Close client tcp error"));
  return -1;
 }  
 else
  return 0;
}

void TCPClientSingle::Stop()
{
 connected = FALSE;
 boost::detail::Sleep(500);

 close();
}

void TCPClientSingle::read_data()
{
 if (!connected)
 {
  return;
 }

 int size = 0;
 while(connected)
 {
  size = 0;
  if (client_stream_.recv_n((BYTE*)&size, 4, 0) == -1)
  {
   boost::detail::Sleep(1);
  }
  else
  {
   if (size < 0)
   {
    client_stream_.close();
    break;
   }
   else
   {
    if(client_stream_.recv_n(data_buf_, size, 0) == -1)
    {
     LoggingService::LoggingERROR(_T("data package format error"));
    }
    else
    {
     if (!signal.empty())
     {
      signal(data_buf_, size);
     }
    }
   }
  }
 }
}

 

#pragma once

#include "define.h"
#include "tstring.h"

class INetCommunicate;

class IPCHELPER_API NetCommFactory
{
public:
 NetCommFactory(void);
 ~NetCommFactory(void);

 static INetCommunicate *GetSingleClient(tstring host_addr, int port);
 static INetCommunicate *GetSingleServer(int port);

 static void Release();
};

 

#include "NetCommFactory.h"
#include "INetCommunicate.h"
#include "TCPClientSingle.h"
#include "TCPServerSingle.h"
#include "CharSetTransformer.h"
#include "ace/ACE.h"

NetCommFactory::NetCommFactory(void)
{
 
}

NetCommFactory::~NetCommFactory(void)
{
}

void NetCommFactory::Release()
{
 ACE::fini();
}

INetCommunicate *NetCommFactory::GetSingleClient(tstring host_addr, int port)
{
 ACE::init();

 std::string str = CharSetTransformer::ws2s(host_addr);
 INetCommunicate *net = new TCPClientSingle(str.c_str(), port);
 return net;
}

INetCommunicate *NetCommFactory::GetSingleServer(int port)
{
 ACE::init();

 INetCommunicate *net = new TCPServerSingle(port);
 return net;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值