#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;
}