使用异步TCP方式,可在此基础上增加更多功能。
头文件AsioTcp.h:
#pragma once
#include <boost/asio.hpp>
#include
<boost/make_shared.hpp>
#include
<boost/enable_shared_from_this.hpp>
typedef boost::asio::ip::tcp::socket socket_t;
typedef void* socket_handle;
class INetCallback
{
public:
virtual void OnNewConnection(socket_handle
newSocket) = 0;
virtual void OnRecvData(socket_handle socket,
const char* pData, UINT32 nDataSize) = 0;
};
class CTcpSession : public boost::enable_shared_from_this
{
public:
CTcpSession(boost::asio::io_service&
ioService, INetCallback* pINetCallback);
void HandleRead(const
boost::system::error_code& ec, size_t
bytes_transferred);
void HandleWrite(const
boost::system::error_code& ec);
void StartRead();
void SendMsg(const
char* pData, UINT32 nDataSize);
socket_t& GetSocket()
{ return m_socket; }
private:
enum { max_length = 1024 };
char m_dataRecvBuff[max_length];
socket_t m_socket;
INetCallback* m_pINetCallback;
};
class CAsioTcp
{
private:
typedef boost::shared_ptr TcpSessionPtr;
typedef boost::asio::ip::tcp::acceptor
acceptor;
public:
CAsioTcp(INetCallback* pINetCallback);
virtual ~CAsioTcp(void);
void SendMsg(socket_handle
socket, const char* pData, UINT32 nDataSize);
void Start();
private:
void StartAccept();
void AcceptHandler(const
boost::system::error_code& ec, TcpSessionPtr
pTcpSession);
private:
boost::asio::io_service m_ioservice;
boost::shared_ptr m_pAcceptor;
INetCallback* m_pINetCallback;
};
实现文件AsioTcp.cpp:
#include "StdAfx.h"
#include "AsioTcp.h"
#include <boost/thread.hpp>
using namespace boost::asio;
CAsioTcp::CAsioTcp(INetCallback* pINetCallback)
: m_pINetCallback(pINetCallback)
{
m_pAcceptor = boost::make_shared(m_ioservice,
ip::tcp::endpoint(ip::tcp::v4(), 1688));
StartAccept();
}
CAsioTcp::~CAsioTcp(void)
{
}
void CAsioTcp::StartAccept()
{
TcpSessionPtr pTcpSession =
boost::make_shared(m_ioservice, m_pINetCallback);
m_pAcceptor->async_accept(pTcpSession->GetSocket(),
boost::bind(&CAsioTcp::AcceptHandler, this,
boost::asio::placeholders::error, pTcpSession));
}
void CAsioTcp::AcceptHandler( const
boost::system::error_code& ec, TcpSessionPtr
pTcpSession )
{
if (ec)
{
return;
}
if (m_pINetCallback != NULL)
{
m_pINetCallback->OnNewConnection(&pTcpSession);
}
StartAccept();
pTcpSession->StartRead();
}
void CAsioTcp::SendMsg( socket_handle socket, const char* pData,
UINT32 nDataSize )
{
TcpSessionPtr* ppTcpSession =
reinterpret_cast(socket);
(*ppTcpSession)->SendMsg(pData,
nDataSize);
}
void CAsioTcp::Start()
{
m_ioservice.run();
}
CTcpSession::CTcpSession(boost::asio::io_service&
ioService, INetCallback* pINetCallback)
: m_socket(ioService)
, m_pINetCallback(pINetCallback)
{
}
void CTcpSession::HandleRead( const
boost::system::error_code& ec, size_t
bytes_transferred )
{
if (!ec)
{
if (m_pINetCallback !=
NULL)
{
m_pINetCallback->OnRecvData(this,
m_dataRecvBuff, bytes_transferred);
}
StartRead();
}
}
void CTcpSession::StartRead()
{
m_socket.async_read_some(boost::asio::buffer(m_dataRecvBuff,
max_length),
boost::bind(&CTcpSession::HandleRead,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void CTcpSession::SendMsg( const char* pData, UINT32 nDataSize
)
{
boost::asio::async_write(m_socket,
boost::asio::buffer(pData,
nDataSize),
boost::bind(&CTcpSession::HandleWrite,
shared_from_this(),
boost::asio::placeholders::error));
}
void CTcpSession::HandleWrite( const
boost::system::error_code& ec )
{
}
这个类使用方法示例:
TestAsioTcpServer.cpp文件:
#include
"stdafx.h"
#include <iostream>
#include "AsioTcp.h"
#include <boost/make_shared.hpp>
class CTestAsioTcpServer : public INetCallback
{
public:
CTestAsioTcpServer()
{
m_pAsioTcp =
boost::make_shared(this);
m_pAsioTcp->Start();
}
void Run()
{
while (true)
{
Sleep(10);
}
}
virtual void OnNewConnection( socket_handle
newSocket )
{
std::cout
<< "OnNewConnection"
<< std::endl;
}
virtual void OnRecvData( socket_handle socket,
const char* pData, UINT32 nDataSize )
{
std::cout
<< "OnRecvData:"
<< pData
<< " size="
<< nDataSize
<< std::endl;
m_pAsioTcp->SendMsg(socket,
"echo", 4);
}
private:
boost::shared_ptr m_pAsioTcp;
};
int _tmain(int argc, _TCHAR* argv[])
{
CTestAsioTcpServer tcpSrv;
tcpSrv.Run();
return 0;
}
客户端代码:
TestAsioTcpClient.cpp文件:
#include "stdafx.h"
#include <boost/asio.hpp>
#include <vector>
using namespace boost::asio;
int _tmain(int argc, _TCHAR* argv[])
{
io_service ioservice;
ip::tcp::socket sock(ioservice);
ip::tcp::endpoint
ep(ip::address::from_string("127.0.0.1"), 1688);
ioservice.run();
try
{
sock.connect(ep);
while (true)
{
char szData[]
= "hello";
std::cout
<< "send:"
<< szData
<< std::endl;
sock.send(buffer(szData));
Sleep(1000);
std::vector<char>
str(1024, 0);
int nSize =
sock.read_some(buffer(str));
std::cout
<< "Recv from "
<< sock.remote_endpoint().address()
<< ":"
<<
&str[0]
<< " size="
<< nSize
<< std::endl;
}
}
catch (std::exception& e)
{
std::cout
<< e.what()
<< std::endl;
}
return 0;
}
以上代码在vs2010下编译通过
加载中,请稍候......