原文: http://blog.csdn.net/byxdaz/article/details/79244800
这个在boost1.64下是报错的,
boost::array<char,TCP_RECV_DATA_PACKAGE_MAX_LENGTH> m_rbTempRecvBuffer;
报不完整的类型,把boost去掉,引用std的array,异常就消失了
异步不能连接回调
tcpclient.h
- #pragma once
- #include <boost/function.hpp>
- #include <boost/bind.hpp>
- #include <boost/asio.hpp>
- #include <boost/shared_ptr.hpp>
- #include <iostream>
- #include <vector>
- #include <string>
- using namespace boost::asio;
- #define TCP_RECV_DATA_PACKAGE_MAX_LENGTH 1024
- //接收数据类型
- typedef enum RecvDataType
- {
- RecvDataType_NoKnown = 0x00, //未知
- RecvDataType_Head = 0x01, //头数据
- RecvDataType_Body = 0x02, //体数据
- RecvDataType_Some = 0x03, //部分数据
- RecvDataType_OnePackage = 0x04, //整包数据
- };
- //发送数据回调函数
- typedef void (CALLBACK *TcpSendDataCallback)(const boost::system::error_code& error,std::size_t bytes_transferred,DWORD dwUserData1,DWORD dwUserData2);
- //接收数据回调函数
- typedef void (CALLBACK *TcpRecvDataCallback)(const boost::system::error_code& error,char *pData,int nDataSize,DWORD dwUserData1,DWORD dwUserData2);
- class TcpClient
- {
- public:
- TcpClient(void);
- virtual ~TcpClient(void);
- //设置参数
- void SetParameter(unsigned int uiSendBufferSize,unsigned int uiSendTimeout,unsigned int uiRecvBufferSize,unsigned int uiRecvTimeout);
- //设置阻塞与非阻塞
- void SetNoBlock(bool bNoBlock);
- //连接服务器(同步)
- int ConnectServer(char *pIp,unsigned short usPort,unsigned int uiConnectTimeout);
- //连接服务器(异步)
- int ConnectServerByAynsc(char *pIp,unsigned short usPort,unsigned int uiConnectTimeout,unsigned int uiReconnectInteralTime);
- //关闭连接
- void CloseConnect();
- //发送数据
- int SendData(char *pBuffer,int nBufferSize);
- //接收数据
- int RecvData(char *pBuffer,int nBufferSize);
- //接收数据(阻塞)
- int RecvDataByBlock(char *pBuffer,int nBufferSize);
- //发送数据(异步)
- int SendDataByAynsc(char *pBuffer,int nBufferSize,TcpSendDataCallback fnCallback,DWORD dwUserData1,DWORD dwUserData2);
- //接收数据(异步)
- int RecvDataByAynsc(TcpRecvDataCallback fnCallback,DWORD dwUserData1,DWORD dwUserData2);
- protected:
- void connect_handler(const boost::system::error_code& ec);
- void async_read_handler(const boost::system::error_code& ec,size_t bytes_transferred,TcpRecvDataCallback fnCallback,DWORD dwUserData1,DWORD dwUserData2);
- void read_hander(char *pBuffer,size_t bytes_transferred,const boost::system::error_code& err);
- void write_handler(const boost::system::error_code& error,size_t bytes_transferred,TcpSendDataCallback fnCallback,DWORD dwUserData1,DWORD dwUserData2);
- void RecvDataTimeoutProcess();
- io_service m_io;
- ip::tcp::endpoint * m_pEndPoint;
- ip::tcp::socket * m_pSocket;
std::array<char, TCP_RECV_DATA_PACKAGE_MAX_LENGTH> m_rbTempRecvBuffer; //临时接收数据缓冲区
//boost::array<char,TCP_RECV_DATA_PACKAGE_MAX_LENGTH> m_rbTempRecvBuffer; //临时接收数据缓冲区
- int m_nSyncRecviceDataSize; //同步接收数据大小
- unsigned int m_uiSendBufferSize;
- unsigned int m_uiSendTimeout;
- unsigned int m_uiRecvBufferSize;
- unsigned int m_uiRecvTimeout;
- deadline_timer * m_pTimer;
- };
tcpclient.cpp
- #include "StdAfx.h"
- #include "TcpClient.h"
- TcpClient::TcpClient(void)
- {
- m_uiSendBufferSize = 0;
- m_uiSendTimeout = 10000;
- m_uiRecvBufferSize = 0;
- m_uiRecvTimeout = 10000;
- m_pEndPoint = NULL;
- m_pSocket = NULL;
- m_nSyncRecviceDataSize = 0;
- m_pTimer = new deadline_timer(m_io);
- }
- TcpClient::~TcpClient(void)
- {
- }
- //设置参数
- void TcpClient::SetParameter(unsigned int uiSendBufferSize,unsigned int uiSendTimeout,unsigned int uiRecvBufferSize,unsigned int uiRecvTimeout)
- {
- m_uiSendBufferSize = uiSendBufferSize;
- m_uiSendTimeout = uiSendTimeout;
- m_uiRecvBufferSize = uiRecvBufferSize;
- m_uiRecvTimeout = uiRecvTimeout;
- if(m_uiRecvTimeout <= 0)
- {
- m_uiRecvTimeout = 10000;
- }
- }
- //连接服务器(同步)
- int TcpClient::ConnectServer(char *pIp,unsigned short usPort,unsigned int uiConnectTimeout)
- {
- if(pIp == NULL || usPort == 0)
- return -1;
- try
- {
- m_pEndPoint = new ip::tcp::endpoint(ip::address::from_string(pIp), usPort);
- m_pSocket = new ip::tcp::socket(m_io);
- m_pSocket->open(m_pEndPoint->protocol());
- m_pSocket->set_option(boost::asio::ip::tcp::socket::reuse_address(true));
- if(m_uiSendBufferSize != 0)
- {
- boost::asio::socket_base::send_buffer_size sendBufferSize(m_uiSendBufferSize);
- m_pSocket->set_option(sendBufferSize);
- }
- if(m_uiRecvBufferSize != 0)
- {
- boost::asio::socket_base::receive_buffer_size recvBufferSize(m_uiRecvBufferSize);
- m_pSocket->set_option(recvBufferSize);
- }
- //connect
- m_pSocket->connect(*m_pEndPoint);
- /*
- char str[1024];
- sock.read_some(buffer(str));
- std::cout << "receive from" << sock.remote_endpoint().address() << std::endl;;
- std::cout << str << std::endl;
- */
- }
- catch (std::exception& e)
- {
- std::cout << e.what() << std::endl;
- return -2;
- }
- return 0;
- }
- //连接服务器(异步)
- int TcpClient::ConnectServerByAynsc(char *pIp,unsigned short usPort,unsigned int uiConnectTimeout,unsigned int uiReconnectInteralTime)
- {
- if(pIp == NULL || usPort == 0)
- return -1;
- try
- {
- m_pEndPoint = new ip::tcp::endpoint(ip::address::from_string(pIp), usPort);
- m_pSocket = new ip::tcp::socket(m_io);
- m_pSocket->open(m_pEndPoint->protocol());
- m_pSocket->set_option(boost::asio::ip::tcp::socket::reuse_address(true));
- if(m_uiSendBufferSize != 0)
- {
- boost::asio::socket_base::send_buffer_size sendBufferSize(m_uiSendBufferSize);
- m_pSocket->set_option(sendBufferSize);
- }
- if(m_uiRecvBufferSize != 0)
- {
- boost::asio::socket_base::receive_buffer_size recvBufferSize(m_uiRecvBufferSize);
- m_pSocket->set_option(recvBufferSize);
- }
- //connect
- m_pSocket->async_connect(*m_pEndPoint,boost::bind(&TcpClient::connect_handler,this, boost::asio::placeholders::error));
- }
- catch (std::exception& e)
- {
- std::cout << e.what() << std::endl;
- return -2;
- }
- return 0;
- }
- void TcpClient::connect_handler(const boost::system::error_code& ec)
- {
- if (ec)
- {
- return;
- }
- std::cout << "receive from:" << m_pSocket->remote_endpoint().address() << std::endl;
- }
- void TcpClient::async_read_handler(const boost::system::error_code& ec,size_t bytes_transferred,TcpRecvDataCallback fnCallback,DWORD dwUserData1,DWORD dwUserData2)
- {
- //回调数据
- if(fnCallback != NULL)
- {
- fnCallback(ec,m_rbTempRecvBuffer.data(),bytes_transferred,dwUserData1,dwUserData2);
- }
- if(ec == boost::asio::error::eof)
- {
- //对端方关闭连接
- if(m_pSocket->is_open())
- {
- m_pSocket->close();
- }
- //printf("close connect \n");
- return;
- }
- if(ec != NULL)
- {
- //发送数据失败
- return;
- }
- //接收下一条数据
- m_pSocket->async_read_some(boost::asio::buffer(m_rbTempRecvBuffer),
- boost::bind(&TcpClient::async_read_handler, this,
- boost::asio::placeholders::error,
- boost::asio::placeholders::bytes_transferred,
- fnCallback,dwUserData1,dwUserData2));
- }
- //关闭连接
- void TcpClient::CloseConnect()
- {
- if(m_pSocket != NULL)
- {
- m_pSocket->close();
- m_pSocket = NULL;
- }
- }
- //发送数据
- int TcpClient::SendData(char *pBuffer,int nBufferSize)
- {
- int nRet = 0;
- if(m_pSocket != NULL)
- {
- nRet = m_pSocket->send(buffer(pBuffer,nBufferSize));
- }
- return nRet;
- }
- //接收数据
- int TcpClient::RecvData(char *pBuffer,int nBufferSize)
- {
- int nRet = 0;
- if(m_pSocket != NULL)
- {
- m_nSyncRecviceDataSize = 0;
- boost::system::error_code ec;
- m_pSocket->async_read_some(buffer(pBuffer,nBufferSize),boost::bind(&TcpClient::read_hander,this,pBuffer,boost::asio::placeholders::bytes_transferred,boost::asio::placeholders::error));
- m_pTimer->expires_from_now(boost::posix_time::seconds(m_uiRecvTimeout));
- m_pTimer->async_wait(boost::bind(&TcpClient::RecvDataTimeoutProcess,this));
- m_io.reset();
- m_io.run(ec);
- nRet = m_nSyncRecviceDataSize;
- }
- return nRet;
- }
- void TcpClient::read_hander(char *pBuffer,size_t bytes_transferred,const boost::system::error_code& err)
- {
- if (err)
- {
- return;
- }
- m_nSyncRecviceDataSize = bytes_transferred;
- m_pTimer->cancel();
- }
- void TcpClient::RecvDataTimeoutProcess()
- {
- int n = 0;
- }
- //接收数据(阻塞)
- int TcpClient::RecvDataByBlock(char *pBuffer,int nBufferSize)
- {
- int nRet = 0;
- if(m_pSocket != NULL)
- {
- m_nSyncRecviceDataSize = 0;
- boost::system::error_code ec;
- m_pSocket->receive(buffer(pBuffer,nBufferSize));
- }
- return nRet;
- }
- //发送数据(异步)
- int TcpClient::SendDataByAynsc(char *pBuffer,int nBufferSize,TcpSendDataCallback fnCallback,DWORD dwUserData1,DWORD dwUserData2)
- {
- if(pBuffer == NULL || nBufferSize == 0)
- return -1;
- if(m_pSocket == NULL || !m_pSocket->is_open())
- return -1;
- boost::asio::async_write(
- *m_pSocket,
- boost::asio::buffer(pBuffer,nBufferSize),
- boost::bind(&TcpClient::write_handler, this,
- boost::asio::placeholders::error,
- boost::asio::placeholders::bytes_transferred,
- fnCallback,dwUserData1,dwUserData2));
- return 0;
- }
- //接收数据(异步)
- int TcpClient::RecvDataByAynsc(TcpRecvDataCallback fnCallback,DWORD dwUserData1,DWORD dwUserData2)
- {
- if(m_pSocket == NULL || !m_pSocket->is_open())
- return -1;
- m_pSocket->async_read_some(buffer(m_rbTempRecvBuffer),boost::bind(&TcpClient::async_read_handler, this, boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred,fnCallback,dwUserData1,dwUserData2));
- return 0;
- }
- //设置阻塞与非阻塞
- void TcpClient::SetNoBlock(bool bNoBlock)
- {
- if(m_pSocket == NULL)
- return;
- if(bNoBlock)
- {
- boost::asio::ip::tcp::socket::non_blocking_io io_option(true);
- m_pSocket->io_control(io_option);
- }
- else
- {
- //阻塞
- boost::asio::ip::tcp::socket::non_blocking_io io_option(false);
- m_pSocket->io_control(io_option);
- }
- }
- void TcpClient::write_handler(const boost::system::error_code& error,size_t bytes_transferred,TcpSendDataCallback fnCallback,DWORD dwUserData1,DWORD dwUserData2)
- {
- if(fnCallback != NULL)
- {
- fnCallback(error,bytes_transferred,dwUserData1,dwUserData2);
- }
- if(error == boost::asio::error::eof)
- {
- //对端方关闭连接
- if(m_pSocket->is_open())
- {
- m_pSocket->close();
- }
- //printf("close connect \n");
- return;
- }
- if(error != NULL)
- {
- //发送数据失败
- return;
- }
- #ifdef _DEBUG
- //写数据
- printf("write data!!!\n");
- #endif
- }