boost库之tcp server(异步)
原文:http://blog.csdn.net/byxdaz/article/details/72676000
//服务端
boost1.64 报错:
boost::array<char, 128> buf;
#include"stdafx.h"
#include<iostream>
#include<boost/shared_ptr.hpp>
#include<boost/asio.hpp>
#include<boost/asio/placeholders.hpp>
#include<boost/system/error_code.hpp>
#include<boost/bind/bind.hpp>
#include"TcpServerSocket.hpp"
usingnamespace std;
#defineTCP_RECV_DATA_PACKAGE_MAX_LENGTH 2048
#defineTCP_SEND_DATA_PACKAGE_MAX_LENGTH 2048
#include<iostream>
#include<boost/function.hpp>
#include<boost/enable_shared_from_this.hpp>
usingnamespace boost::asio;
std::stringmake_daytime_string()
{
usingnamespace std;
time_t now = std::time(NULL);
return ctime(&now);
}
//发生数据回调函数
typedefvoid (CALLBACK *SendDataCallback)(const boost::system::error_code& error, std::size_t bytes_transferred, DWORD dwUserData1, DWORD dwUserData2);
//接收数据回调函数
typedefvoid (CALLBACK *RecvDataCallback)(const boost::system::error_code& error, char *pData, int nDataSize, DWORD dwUserData1, DWORD dwUserData2);
//tcp connection
classTcpConnection
{
public:
staticTcpConnection * create(io_service& ioService)
{
returnnewTcpConnection(ioService);
}
virtual ~TcpConnection()
{
m_bDisconnect= true;
m_socket.close();
}
ip::tcp::socket& socket()
{
/* m_socket.set_option(
boost::asio::ip::tcp::socket::(true));*/
return m_socket;
}
//发送数据
int sendData(char *pData, intnDataSize, SendDataCallbackfnCallback, DWORDdwUserData1, DWORDdwUserData2)
{
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, DWORDdwUserData1, DWORDdwUserData2)
{
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_tbytes_transferred, SendDataCallbackfnCallback, DWORDdwUserData1, DWORDdwUserData2)
{
if (fnCallback != NULL)
{
fnCallback(error, bytes_transferred, dwUserData1, dwUserData2);
}
if (error==boost::asio::error::eof)
{
//对端方关闭连接
m_bDisconnect= true;
if(m_socket.is_open())
{
m_socket.close();
}
if (!m_bDisconnect)
{
printf("close connect \n");
}
return;
}
if (error != NULL)
{
//发送数据失败
return;
}
printf("write data!!!");
}
void handle_read(const boost::system::error_code& error, size_tbytes_transferred, RecvDataCallback fnCallback, DWORDdwUserData1, DWORDdwUserData2)
{
if (fnCallback != NULL)
{
fnCallback(error, m_recvBuf.data(), bytes_transferred, dwUserData1, dwUserData2);
}
if (error==boost::asio::error::eof)
{
//对端方关闭连接
if(m_socket.is_open())
{
m_socket.close();
}
printf("close connect \n");
return;
}
if (error != NULL)
{
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; //发送数据缓冲区
array<char, TCP_RECV_DATA_PACKAGE_MAX_LENGTH> m_recvBuf; //接收数据缓冲区
array<char, TCP_SEND_DATA_PACKAGE_MAX_LENGTH> m_sendBuf; //发送数据缓冲区
};
classTcpServer
{
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;
//设置新建连接回调函数
voidsetNewConnectionCallback(CreateConnnectionCallbackHandlerfnHandler, intnUserData)
{
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.set_option(
boost::asio::ip::tcp::acceptor::reuse_address(true));
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)
{
string ipp=m_acceptor.local_endpoint().address().to_string();
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);
deletepTcpConnectionTmpObject;
}
iter++;
}
g_listNoEffectConnection.clear();
}
}
//新连接回调处理
void NewConnectionCallbackProcess(TcpConnection * new_connection, intnUserData)
{
g_listConnection.push_back(new_connection);
}
voidWINAPI RecvDataCallbackProcess(const boost::system::error_code& error, char *pData, intnDataSize, DWORDdwUserData1, DWORDdwUserData2)
{
if (error==boost::asio::error::eof)
{
//对端方关闭连接
TcpConnection *pTcpConnectionTmpObject = (TcpConnection *)dwUserData1;
if(pTcpConnectionTmpObject != NULL)
{
InsertNoEffectConnection(pTcpConnectionTmpObject);
}
return;
}
}
int main(intargc, 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)
{
deletepTcpConnectionObject;
}
}
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.com", "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 == boost::asio::error::eof)
- {
- break; // Connection closed cleanly by peer.
- }
- else if (error)
- {
- 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 server(异步)相关推荐
- boost库之tcp client 回调不正常
原文: http://blog.csdn.net/byxdaz/article/details/79244800 这个在boost1.64下是报错的, boost::array<char,TCP ...
- boost库之udp server实例
//UdpLinkServer.h //udp服务#pragma once#include <boost/asio/ip/tcp.hpp> #include <boost/asio. ...
- boost库之tcp实例(同步方式)
原文:http://blog.csdn.net/byxdaz/article/details/72627678 //服务端 [cpp] view plaincopy #include <iost ...
- Boost库网络编程
Boost库网络编程和异步IO(一) boost::asio概要 boost::aiso主要用于跨平台网络开发,封装了底层常用的网络操作和同步.异步IO操作,可以很快速的设计开发出高并发网络服务程序. ...
- 基于boost asio实现sync tcp server通信
文章目录 一.功能介绍 二.string类型数据交互 2.1 程序源码 2.2 编译&&执行 2.3 程序执行结果 三.byte类型数据交互 3.1 程序源码 3.2 编译&& ...
- 【Boost】boost库asio详解8——TCP的简单例子1
摘于boost官网的几个例子, 做了点小修改, 笔记之. 同步客户端 [cpp] view plain copy print? void test_asio_synclient() { typede ...
- Boost库实现线程池学习及线程实现的异步调用
A.Boost线程池实现 参考自: Boost库实现线程池实例 原理:使用boost的thread_group存储多个线程,使用bind方法将要处理的函数转换成线程可调用的函数进行执行:使用队列存储待 ...
- 【Boost】boost库asio详解9——TCP的简单例子2
客户端: // Client.cpp : 定义控制台应用程序的入口点. //#include "stdafx.h" #include <iostream> #inclu ...
- boost asio 文件服务器,使用boost ASIO库封装TCP服务器类
使用异步TCP方式,可在此基础上增加更多功能. 头文件AsioTcp.h: #pragma once #include #include #include typedef boost::asio::i ...
最新文章
- C++的STL栈实现获取栈中最小元素的成员
- 科研经验3:公众号建立实验室共享知识体系和宣传窗口
- MyBatis入门学习教程-调用存储过程
- 《LeetCode力扣练习》第75题 颜色分类 Java
- java B2B2C Springcloud多租户电子商城系统-docker-feign-hystrix-ribbon(七)
- 【软件工程-Teamwork 3】团队角色分配和团队贡献分分配规则
- ORA-01033: ORACLE initialization or shutdown in progress
- 5调色板怎么打开_CAD打开较大的图纸就卡死的解决方法
- 7-100 倒数第N个字符串 (15 分)
- dedecms 找后台总结_总结找到后台路径的N总思路方法
- TortoiseSVN 命令 (命令行执行工具)
- 隐马尔可夫模型通俗导论
- 分治算法实现经典归并排序java实现
- 去掉txt文本某些字符
- SSE图像算法优化系列十五:YUV/XYZ和RGB空间相互转化的极速实现(此后老板不用再担心算法转到其他空间通道的耗时了)。...
- View之ExpandableLists
- 华为服务器麒麟系统,通用服务器麒麟os
- 人生之路1.20代码 第二部分
- Linux中光盘使用的文件类型,Linux光盘行动之制作光盘
- 追书神器 三星s8+ 语音朗读锁屏后中断问题解决办法
热门文章
- TCP校验和的设计与实现
- leetcode327 超时大坑
- 认识计算机硬件观评课,观课听课评课评语
- c语言数位递增的数解题思路,【菜鸟求助】21位数的花朵数问题,求解题思路
- matlab中fdyn,Matlab的用法总结
- 超级计算机在线解方程,量子计算机10秒可得超级计算机百年运算结果
- android中的定时任务一般有两种机制,android 定时任务
- java项目集成mybatis_JAVA应用程序单独集成Mybatis使用Demo
- 皮一皮:论脑回路的新奇指数...
- 音效摸鱼还不够爽?试试IDE里打几盘魂斗罗?