boost库之tcp client 回调不正常

原文: 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

[cpp]  view plain  copy
  1. #pragma once  
  2.   
  3. #include <boost/function.hpp>  
  4. #include <boost/bind.hpp>  
  5. #include <boost/asio.hpp>  
  6. #include <boost/shared_ptr.hpp>  
  7. #include <iostream>  
  8. #include <vector>  
  9. #include <string>  
  10. using namespace boost::asio;  
  11.   
  12. #define         TCP_RECV_DATA_PACKAGE_MAX_LENGTH                1024  
  13.   
  14. //接收数据类型  
  15. typedef enum RecvDataType  
  16. {  
  17.     RecvDataType_NoKnown        =       0x00,           //未知  
  18.     RecvDataType_Head           =       0x01,           //头数据  
  19.     RecvDataType_Body           =       0x02,           //体数据  
  20.     RecvDataType_Some           =       0x03,           //部分数据  
  21.     RecvDataType_OnePackage     =       0x04,           //整包数据  
  22. };  
  23.   
  24. //发送数据回调函数  
  25. typedef void (CALLBACK *TcpSendDataCallback)(const boost::system::error_code& error,std::size_t bytes_transferred,DWORD dwUserData1,DWORD dwUserData2);  
  26.   
  27. //接收数据回调函数  
  28. typedef void (CALLBACK *TcpRecvDataCallback)(const boost::system::error_code& error,char *pData,int nDataSize,DWORD dwUserData1,DWORD dwUserData2);  
  29.   
  30. class TcpClient  
  31. {  
  32. public:  
  33.     TcpClient(void);  
  34.     virtual ~TcpClient(void);  
  35.   
  36.     //设置参数  
  37.     void    SetParameter(unsigned int uiSendBufferSize,unsigned int uiSendTimeout,unsigned int uiRecvBufferSize,unsigned int uiRecvTimeout);  
  38.   
  39.     //设置阻塞与非阻塞  
  40.     void    SetNoBlock(bool bNoBlock);  
  41.   
  42.     //连接服务器(同步)  
  43.     int     ConnectServer(char *pIp,unsigned short usPort,unsigned int uiConnectTimeout);  
  44.   
  45.     //连接服务器(异步)  
  46.     int     ConnectServerByAynsc(char *pIp,unsigned short usPort,unsigned int uiConnectTimeout,unsigned int uiReconnectInteralTime);  
  47.   
  48.     //关闭连接  
  49.     void    CloseConnect();  
  50.   
  51.     //发送数据  
  52.     int     SendData(char *pBuffer,int nBufferSize);  
  53.   
  54.     //接收数据  
  55.     int     RecvData(char *pBuffer,int nBufferSize);  
  56.   
  57.     //接收数据(阻塞)  
  58.     int     RecvDataByBlock(char *pBuffer,int nBufferSize);  
  59.   
  60.     //发送数据(异步)  
  61.     int     SendDataByAynsc(char *pBuffer,int nBufferSize,TcpSendDataCallback fnCallback,DWORD dwUserData1,DWORD dwUserData2);  
  62.   
  63.     //接收数据(异步)  
  64.     int     RecvDataByAynsc(TcpRecvDataCallback fnCallback,DWORD dwUserData1,DWORD dwUserData2);  
  65.   
  66. protected:  
  67.     void connect_handler(const boost::system::error_code& ec);  
  68.     void async_read_handler(const boost::system::error_code& ec,size_t bytes_transferred,TcpRecvDataCallback fnCallback,DWORD dwUserData1,DWORD dwUserData2);  
  69.     void read_hander(char *pBuffer,size_t bytes_transferred,const boost::system::error_code& err);  
  70.     void write_handler(const boost::system::error_code& error,size_t bytes_transferred,TcpSendDataCallback fnCallback,DWORD dwUserData1,DWORD dwUserData2);  
  71.   
  72.     void RecvDataTimeoutProcess();  
  73.   
  74.     io_service m_io;  
  75.     ip::tcp::endpoint * m_pEndPoint;  
  76.     ip::tcp::socket * m_pSocket;  
  77.     std::array<char, TCP_RECV_DATA_PACKAGE_MAX_LENGTH> m_rbTempRecvBuffer;       //临时接收数据缓冲区 

        //boost::array<char,TCP_RECV_DATA_PACKAGE_MAX_LENGTH> m_rbTempRecvBuffer;       //临时接收数据缓冲区  

  78.   
  79.     int m_nSyncRecviceDataSize;             //同步接收数据大小  
  80.   
  81.     unsigned int m_uiSendBufferSize;  
  82.     unsigned int m_uiSendTimeout;  
  83.     unsigned int m_uiRecvBufferSize;  
  84.     unsigned int m_uiRecvTimeout;  
  85.   
  86.     deadline_timer * m_pTimer;  
  87. };  

tcpclient.cpp

[cpp]  view plain  copy
  1. #include "StdAfx.h"  
  2. #include "TcpClient.h"  
  3.   
  4. TcpClient::TcpClient(void)  
  5. {  
  6.     m_uiSendBufferSize = 0;  
  7.     m_uiSendTimeout = 10000;  
  8.     m_uiRecvBufferSize = 0;  
  9.     m_uiRecvTimeout = 10000;  
  10.     m_pEndPoint = NULL;  
  11.     m_pSocket = NULL;  
  12.     m_nSyncRecviceDataSize = 0;  
  13.     m_pTimer = new deadline_timer(m_io);  
  14. }  
  15.   
  16. TcpClient::~TcpClient(void)  
  17. {  
  18. }  
  19.   
  20. //设置参数  
  21. void    TcpClient::SetParameter(unsigned int uiSendBufferSize,unsigned int uiSendTimeout,unsigned int uiRecvBufferSize,unsigned int uiRecvTimeout)  
  22. {  
  23.     m_uiSendBufferSize = uiSendBufferSize;  
  24.     m_uiSendTimeout = uiSendTimeout;  
  25.     m_uiRecvBufferSize = uiRecvBufferSize;  
  26.     m_uiRecvTimeout = uiRecvTimeout;  
  27.     if(m_uiRecvTimeout <= 0)  
  28.     {  
  29.         m_uiRecvTimeout = 10000;  
  30.     }  
  31. }  
  32.   
  33.   
  34. //连接服务器(同步)  
  35. int     TcpClient::ConnectServer(char *pIp,unsigned short usPort,unsigned int uiConnectTimeout)  
  36. {  
  37.     if(pIp == NULL || usPort == 0)  
  38.         return -1;  
  39.   
  40.     try  
  41.     {  
  42.         m_pEndPoint = new ip::tcp::endpoint(ip::address::from_string(pIp), usPort);  
  43.         m_pSocket = new ip::tcp::socket(m_io);  
  44.         m_pSocket->open(m_pEndPoint->protocol());  
  45.         m_pSocket->set_option(boost::asio::ip::tcp::socket::reuse_address(true));  
  46.         if(m_uiSendBufferSize != 0)  
  47.         {  
  48.             boost::asio::socket_base::send_buffer_size sendBufferSize(m_uiSendBufferSize);  
  49.             m_pSocket->set_option(sendBufferSize);  
  50.         }  
  51.         if(m_uiRecvBufferSize != 0)  
  52.         {  
  53.             boost::asio::socket_base::receive_buffer_size recvBufferSize(m_uiRecvBufferSize);  
  54.             m_pSocket->set_option(recvBufferSize);  
  55.         }  
  56.         //connect  
  57.         m_pSocket->connect(*m_pEndPoint);  
  58.         /* 
  59.         char str[1024]; 
  60.         sock.read_some(buffer(str)); 
  61.         std::cout << "receive from" << sock.remote_endpoint().address() << std::endl;; 
  62.         std::cout << str << std::endl; 
  63.         */  
  64.     }  
  65.     catch (std::exception& e)  
  66.     {  
  67.         std::cout << e.what() << std::endl;  
  68.         return -2;  
  69.     }  
  70.   
  71.     return 0;  
  72. }  
  73.   
  74. //连接服务器(异步)  
  75. int TcpClient::ConnectServerByAynsc(char *pIp,unsigned short usPort,unsigned int uiConnectTimeout,unsigned int uiReconnectInteralTime)  
  76. {  
  77.     if(pIp == NULL || usPort == 0)  
  78.         return -1;  
  79.   
  80.     try  
  81.     {  
  82.         m_pEndPoint = new ip::tcp::endpoint(ip::address::from_string(pIp), usPort);  
  83.         m_pSocket = new ip::tcp::socket(m_io);  
  84.         m_pSocket->open(m_pEndPoint->protocol());  
  85.         m_pSocket->set_option(boost::asio::ip::tcp::socket::reuse_address(true));  
  86.         if(m_uiSendBufferSize != 0)  
  87.         {  
  88.             boost::asio::socket_base::send_buffer_size sendBufferSize(m_uiSendBufferSize);  
  89.             m_pSocket->set_option(sendBufferSize);  
  90.         }  
  91.         if(m_uiRecvBufferSize != 0)  
  92.         {  
  93.             boost::asio::socket_base::receive_buffer_size recvBufferSize(m_uiRecvBufferSize);  
  94.             m_pSocket->set_option(recvBufferSize);  
  95.         }  
  96.         //connect  
  97.         m_pSocket->async_connect(*m_pEndPoint,boost::bind(&TcpClient::connect_handler,this, boost::asio::placeholders::error));  
  98.     }  
  99.     catch (std::exception& e)  
  100.     {  
  101.         std::cout << e.what() << std::endl;  
  102.         return -2;  
  103.     }  
  104.   
  105.     return 0;  
  106. }  
  107.   
  108. void TcpClient::connect_handler(const boost::system::error_code& ec)  
  109. {  
  110.     if (ec)  
  111.     {  
  112.         return;  
  113.     }  
  114.   
  115.     std::cout << "receive from:" << m_pSocket->remote_endpoint().address() << std::endl;  
  116. }  
  117.   
  118. void TcpClient::async_read_handler(const boost::system::error_code& ec,size_t bytes_transferred,TcpRecvDataCallback fnCallback,DWORD dwUserData1,DWORD dwUserData2)  
  119. {  
  120.     //回调数据  
  121.     if(fnCallback != NULL)  
  122.     {  
  123.         fnCallback(ec,m_rbTempRecvBuffer.data(),bytes_transferred,dwUserData1,dwUserData2);  
  124.     }  
  125.   
  126.     if(ec == boost::asio::error::eof)  
  127.     {  
  128.         //对端方关闭连接  
  129.         if(m_pSocket->is_open())  
  130.         {  
  131.             m_pSocket->close();  
  132.         }  
  133.         //printf("close connect \n");  
  134.         return;  
  135.     }  
  136.     if(ec != NULL)  
  137.     {  
  138.         //发送数据失败  
  139.         return;  
  140.     }  
  141.   
  142.     //接收下一条数据  
  143.     m_pSocket->async_read_some(boost::asio::buffer(m_rbTempRecvBuffer),  
  144.         boost::bind(&TcpClient::async_read_handler, this,   
  145.         boost::asio::placeholders::error,   
  146.         boost::asio::placeholders::bytes_transferred,  
  147.         fnCallback,dwUserData1,dwUserData2));  
  148. }  
  149.   
  150. //关闭连接  
  151. void    TcpClient::CloseConnect()  
  152. {  
  153.     if(m_pSocket != NULL)  
  154.     {  
  155.         m_pSocket->close();  
  156.         m_pSocket = NULL;  
  157.     }  
  158. }  
  159.   
  160.   
  161. //发送数据  
  162. int     TcpClient::SendData(char *pBuffer,int nBufferSize)  
  163. {  
  164.     int nRet = 0;  
  165.     if(m_pSocket != NULL)  
  166.     {  
  167.         nRet = m_pSocket->send(buffer(pBuffer,nBufferSize));  
  168.     }  
  169.   
  170.     return nRet;  
  171. }  
  172.   
  173. //接收数据  
  174. int     TcpClient::RecvData(char *pBuffer,int nBufferSize)  
  175. {  
  176.     int nRet = 0;  
  177.     if(m_pSocket != NULL)  
  178.     {  
  179.         m_nSyncRecviceDataSize = 0;  
  180.         boost::system::error_code ec;  
  181.         m_pSocket->async_read_some(buffer(pBuffer,nBufferSize),boost::bind(&TcpClient::read_hander,this,pBuffer,boost::asio::placeholders::bytes_transferred,boost::asio::placeholders::error));  
  182.         m_pTimer->expires_from_now(boost::posix_time::seconds(m_uiRecvTimeout));    
  183.         m_pTimer->async_wait(boost::bind(&TcpClient::RecvDataTimeoutProcess,this));  
  184.         m_io.reset();  
  185.         m_io.run(ec);  
  186.         nRet = m_nSyncRecviceDataSize;  
  187.     }  
  188.   
  189.     return nRet;  
  190. }  
  191.   
  192. void TcpClient::read_hander(char *pBuffer,size_t bytes_transferred,const boost::system::error_code& err)  
  193. {  
  194.     if (err)  
  195.     {  
  196.         return;  
  197.     }  
  198.     m_nSyncRecviceDataSize = bytes_transferred;  
  199.     m_pTimer->cancel();  
  200. }   
  201.   
  202. void TcpClient::RecvDataTimeoutProcess()  
  203. {  
  204.     int n = 0;  
  205. }  
  206.   
  207. //接收数据(阻塞)  
  208. int TcpClient::RecvDataByBlock(char *pBuffer,int nBufferSize)  
  209. {  
  210.     int nRet = 0;  
  211.     if(m_pSocket != NULL)  
  212.     {  
  213.         m_nSyncRecviceDataSize = 0;  
  214.         boost::system::error_code ec;  
  215.         m_pSocket->receive(buffer(pBuffer,nBufferSize));  
  216.     }  
  217.   
  218.     return nRet;  
  219. }  
  220.   
  221. //发送数据(异步)  
  222. int     TcpClient::SendDataByAynsc(char *pBuffer,int nBufferSize,TcpSendDataCallback fnCallback,DWORD dwUserData1,DWORD dwUserData2)  
  223. {  
  224.     if(pBuffer == NULL || nBufferSize == 0)  
  225.         return -1;  
  226.   
  227.     if(m_pSocket == NULL || !m_pSocket->is_open())  
  228.         return -1;  
  229.   
  230.     boost::asio::async_write(  
  231.         *m_pSocket,   
  232.         boost::asio::buffer(pBuffer,nBufferSize),   
  233.         boost::bind(&TcpClient::write_handler, this,  
  234.         boost::asio::placeholders::error,   
  235.         boost::asio::placeholders::bytes_transferred,  
  236.         fnCallback,dwUserData1,dwUserData2));  
  237.   
  238.     return 0;  
  239. }  
  240.   
  241. //接收数据(异步)  
  242. int     TcpClient::RecvDataByAynsc(TcpRecvDataCallback fnCallback,DWORD dwUserData1,DWORD dwUserData2)  
  243. {  
  244.     if(m_pSocket == NULL || !m_pSocket->is_open())  
  245.         return -1;  
  246.   
  247.     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));  
  248.       
  249.     return 0;  
  250. }  
  251.   
  252. //设置阻塞与非阻塞  
  253. void TcpClient::SetNoBlock(bool bNoBlock)  
  254. {  
  255.     if(m_pSocket == NULL)  
  256.         return;  
  257.   
  258.     if(bNoBlock)  
  259.     {  
  260.         boost::asio::ip::tcp::socket::non_blocking_io io_option(true);  
  261.         m_pSocket->io_control(io_option);  
  262.     }  
  263.     else  
  264.     {  
  265.         //阻塞  
  266.         boost::asio::ip::tcp::socket::non_blocking_io io_option(false);  
  267.         m_pSocket->io_control(io_option);  
  268.     }  
  269. }  
  270.   
  271. void TcpClient::write_handler(const boost::system::error_code& error,size_t bytes_transferred,TcpSendDataCallback fnCallback,DWORD dwUserData1,DWORD dwUserData2)  
  272. {  
  273.     if(fnCallback != NULL)  
  274.     {  
  275.         fnCallback(error,bytes_transferred,dwUserData1,dwUserData2);  
  276.     }  
  277.     if(error == boost::asio::error::eof)  
  278.     {  
  279.         //对端方关闭连接  
  280.         if(m_pSocket->is_open())  
  281.         {  
  282.             m_pSocket->close();  
  283.         }  
  284.         //printf("close connect \n");  
  285.         return;  
  286.     }  
  287.     if(error != NULL)  
  288.     {  
  289.         //发送数据失败  
  290.         return;  
  291.     }  
  292.   
  293. #ifdef _DEBUG  
  294.     //写数据  
  295.     printf("write data!!!\n");  
  296. #endif  
  297. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI算法网奇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值