boost库之tcp实例(异步方式)

编程入门 行业动态 更新时间:2024-10-11 21:24:13

boost库之tcp<a href=https://www.elefans.com/category/jswz/34/1771375.html style=实例(异步方式)"/>

boost库之tcp实例(异步方式)

//服务端

 

#define	TCP_RECV_DATA_PACKAGE_MAX_LENGTH			2048
#define	TCP_SEND_DATA_PACKAGE_MAX_LENGTH			2048#include <iostream>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/shared_ptr.hpp>using namespace boost::asio;std::string make_daytime_string()
{using namespace std;time_t now = std::time(NULL);return ctime(&now);
}//发生数据回调函数
typedef void (CALLBACK *SendDataCallback)(const boost::system::error_code& error,std::size_t bytes_transferred,DWORD dwUserData1,DWORD dwUserData2);//接收数据回调函数
typedef void (CALLBACK *RecvDataCallback)(const boost::system::error_code& error,char *pData,int nDataSize,DWORD dwUserData1,DWORD dwUserData2);//tcp connection
class TcpConnection
{
public:static TcpConnection * create(io_service& ioService){return new TcpConnection(ioService);}virtual ~TcpConnection(){m_bDisconnect = true;m_socket.close();}ip::tcp::socket& socket(){return m_socket;}//发送数据int sendData(char *pData,int nDataSize,SendDataCallback fnCallback,DWORD dwUserData1,DWORD dwUserData2){if(fnCallback == NULL){//同步if(!m_socket.is_open()){return 0;}std::size_t  nSendedSize = boost::asio::write(m_socket,boost::asio::buffer(pData,nDataSize));if(nDataSize == nSendedSize){return 0;}else{return nSendedSize;}}else{//异步if(!m_socket.is_open()){return 0;}memcpy(m_sendBuf.data(),pData,nDataSize);boost::asio::async_write(m_socket, boost::asio::buffer(m_sendBuf.data(),nDataSize), boost::bind(&TcpConnection::handle_write, this,boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred,fnCallback,dwUserData1,dwUserData2));}return 0;}//接收数据(同步)int	recvDataBySync(){if(!m_socket.is_open()){return 0;}boost::system::error_code error;std::size_t nSize = m_socket.read_some(boost::asio::buffer(m_recvBuf),error);if(error != NULL){//错误return 0;}return nSize;}//接收数据(异步)int	recvDataByAsync(RecvDataCallback  fnCallback,DWORD dwUserData1,DWORD dwUserData2){m_socket.async_read_some(boost::asio::buffer(m_recvBuf),boost::bind(&TcpConnection::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred,fnCallback,dwUserData1,dwUserData2));return 0;}private:TcpConnection(io_service& ioService): m_socket(ioService){m_bDisconnect = false;}void handle_write(const boost::system::error_code& error,size_t bytes_transferred,SendDataCallback fnCallback,DWORD dwUserData1,DWORD dwUserData2){if(fnCallback != NULL){fnCallback(error,bytes_transferred,dwUserData1,dwUserData2);}if(error != NULL){m_bDisconnect = true;if(m_socket.is_open()){m_socket.close();}if(!m_bDisconnect){printf("close connect \n");}//发送数据失败return;}printf("write data!!!");}void handle_read(const boost::system::error_code& error,size_t bytes_transferred,RecvDataCallback  fnCallback,DWORD dwUserData1,DWORD dwUserData2){if(fnCallback != NULL){fnCallback(error,m_recvBuf.data(),bytes_transferred,dwUserData1,dwUserData2);}
if(error != NULL)
{if (error == boost::asio::error::eof || error == boost::asio::error::connection_reset){//boost::asio::error::eof  --对端方关闭连接(正常关闭套接字)//boost::asio::error::connection_reset --对端方关闭连接(暴力关闭套接字)//对端方关闭连接if(m_socket.is_open()){m_socket.close();}printf("close connect \n");}
else
{if(m_socket.is_open()){m_socket.close();}
}
return;
}char szMsg[128] = {0};memcpy(szMsg,m_recvBuf.data(),bytes_transferred);printf("%s \n",szMsg);}bool	m_bDisconnect;											//是否断开连接ip::tcp::socket m_socket;boost::array<char,TCP_RECV_DATA_PACKAGE_MAX_LENGTH> m_recvBuf;	//接收数据缓冲区boost::array<char,TCP_SEND_DATA_PACKAGE_MAX_LENGTH> m_sendBuf;	//发送数据缓冲区
};class TcpServer
{
public:TcpServer(io_service& ioService) : m_acceptor(ioService, ip::tcp::endpoint(ip::tcp::v4(), 10005)){m_funcConnectionHandler = NULL;m_nUserData = 0;m_bStop = false;}//新建连接回调函数typedef boost::function<void (TcpConnection * new_connection,int nUserData)>	CreateConnnectionCallbackHandler;//设置新建连接回调函数void setNewConnectionCallback(CreateConnnectionCallbackHandler fnHandler,int nUserData){m_funcConnectionHandler = fnHandler;m_nUserData = nUserData;}//开始工作void startWork(){m_bStop = false;start_accept();}//停止工作void stopWork(){m_bStop = true;m_acceptor.close();}private:void start_accept(){if(m_bStop){return;}TcpConnection *new_connection = TcpConnection::create(m_acceptor.get_io_service());m_acceptor.async_accept(new_connection->socket(), boost::bind(&TcpServer::handle_accept, this, new_connection, boost::asio::placeholders::error));}void handle_accept(TcpConnection * new_connection,const boost::system::error_code& error){if (!error){if(m_funcConnectionHandler != NULL){m_funcConnectionHandler(new_connection,m_nUserData);}new_connection->sendData("abcdefg",strlen("abcdefg"),NULL,0,0);start_accept();}}ip::tcp::acceptor m_acceptor;CreateConnnectionCallbackHandler m_funcConnectionHandler;int				  m_nUserData;bool			  m_bStop;
};//所有连接
std::list<TcpConnection *> g_listConnection;
//无效连接
std::list<TcpConnection *> g_listNoEffectConnection;//插入无效连接
void InsertNoEffectConnection(TcpConnection * pConnnection)
{bool bFind = false;TcpConnection * pTcpConnectionTmpObject = NULL;std::list<TcpConnection *>::iterator iter,iterEnd;iter = g_listNoEffectConnection.begin();iterEnd = g_listNoEffectConnection.end();for(iter; iter!=iterEnd; iter++){pTcpConnectionTmpObject = *iter;if(pTcpConnectionTmpObject == pConnnection){bFind = true;break;}}//未找到,插入if(!bFind){g_listNoEffectConnection.push_back(pTcpConnectionTmpObject);}
}//删除无效连接
void DeleteNoEffectConnection()
{std::list<TcpConnection *>::iterator iter;if(g_listNoEffectConnection.size() > 0){TcpConnection * pTcpConnectionTmpObject = NULL;iter = g_listNoEffectConnection.begin();while(iter != g_listNoEffectConnection.end()){pTcpConnectionTmpObject = *iter;if(pTcpConnectionTmpObject != NULL){g_listConnection.remove(pTcpConnectionTmpObject);delete pTcpConnectionTmpObject;}iter++;}g_listNoEffectConnection.clear();}
}//新连接回调处理
void NewConnectionCallbackProcess(TcpConnection * new_connection,int nUserData)
{g_listConnection.push_back(new_connection);
}void WINAPI RecvDataCallbackProcess(const boost::system::error_code& error,char *pData,int nDataSize,DWORD dwUserData1,DWORD dwUserData2)
{if (error == boost::asio::error::eof){//对端方关闭连接TcpConnection * pTcpConnectionTmpObject = (TcpConnection *)dwUserData1;if(pTcpConnectionTmpObject != NULL){InsertNoEffectConnection(pTcpConnectionTmpObject);}return;}
}int main(int argc, char* argv[])
{try{io_service ioService;TcpServer server(ioService);server.setNewConnectionCallback(NewConnectionCallbackProcess,0);server.startWork();TcpConnection * pTcpConnectionObject = NULL;std::list<TcpConnection *>::iterator iter,iterEnd;int n = 0;while(true){//删除无效连接DeleteNoEffectConnection();//遍历iter = g_listConnection.begin();iterEnd = g_listConnection.end();for(iter; iter!=iterEnd; iter++){pTcpConnectionObject = *iter;pTcpConnectionObject->sendData("111",3,NULL,0,0);pTcpConnectionObject->recvDataByAsync(RecvDataCallbackProcess,(int)pTcpConnectionObject,0);}ioService.poll();Sleep(200);n++;if(n > 1000){break;}}// 只有io_service类的run()方法运行之后回调对象才会被调用//ioService.run();//释放空间iter = g_listConnection.begin();iterEnd = g_listConnection.end();for(iter; iter!=iterEnd; iter++){pTcpConnectionObject = *iter;if(pTcpConnectionObject != NULL){delete pTcpConnectionObject;}}g_listConnection.clear();server.stopWork();}catch (std::exception& e){std::cout << e.what() << std::endl;}return 0;
}

 

 

 

//客户端

 

#include <iostream>
#include <boost/asio.hpp>
using namespace boost::asio;int main(int argc, char* argv[])
{io_service ioService;boost::system::error_code error;try{//获取ip(用解释器的方法来解析域名)/*ip::tcp::resolver resolver(ioService);ip::tcp::resolver::query query("www.yahoo", "80");ip::tcp::resolver::iterator iter = resolver.resolve( query);ip::tcp::endpoint ep = *iter;std::cout << ep.address().to_string() << std::endl;*/ip::tcp::socket socket(ioService);ip::tcp::endpoint endpoint(boost::asio::ip::address_v4::from_string("127.0.0.1"), 10005);socket.connect(endpoint, error);//是否出错if (error){throw boost::system::system_error(error);}while(true){boost::array<char,128> buf;size_t len = socket.read_some(boost::asio::buffer(buf), error);//服务端运行断开.if(error != NULL)
{if (error == boost::asio::error::eof) {break; // 对端方关闭连接(正常关闭套接字)}else if (error == boost::asio::error::connection_reset){
break;//对端方关闭连接(暴力关闭套接字)}else
{
throw boost::system::system_error(error); // Some other error.}
}char szMsg[128] = {0};memcpy(szMsg,buf.data(),len);printf("%s\n",szMsg);//发送数据socket.write_some(boost::asio::buffer(buf, len), error);}}catch (std::exception& e){printf(e.what());}return 0;
}

 

 

 

更多推荐

boost库之tcp实例(异步方式)

本文发布于:2024-03-05 09:17:24,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1711896.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:实例   方式   boost   tcp

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!