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;

}



//客户端

[cpp]  view plain  copy
  1. #include <iostream>  
  2. #include <boost/asio.hpp>  
  3. using namespace boost::asio;  
  4.   
  5. int main(int argc, char* argv[])  
  6. {  
  7.     io_service ioService;  
  8.     boost::system::error_code error;  
  9.     try  
  10.     {  
  11.         //获取ip(用解释器的方法来解析域名)  
  12.         /* 
  13.         ip::tcp::resolver resolver(ioService); 
  14.         ip::tcp::resolver::query query("www.yahoo.com", "80"); 
  15.         ip::tcp::resolver::iterator iter = resolver.resolve( query); 
  16.         ip::tcp::endpoint ep = *iter; 
  17.         std::cout << ep.address().to_string() << std::endl; 
  18.         */  
  19.   
  20.         ip::tcp::socket socket(ioService);  
  21.         ip::tcp::endpoint endpoint(boost::asio::ip::address_v4::from_string("127.0.0.1"), 10005);  
  22.         socket.connect(endpoint, error);  
  23.   
  24.         //是否出错  
  25.         if (error)  
  26.         {  
  27.             throw boost::system::system_error(error);  
  28.         }  
  29.   
  30.         while(true)  
  31.         {  
  32.             boost::array<char,128> buf;  
  33.             size_t len = socket.read_some(boost::asio::buffer(buf), error);  
  34.             //服务端运行断开.  
  35.             if (error == boost::asio::error::eof)  
  36.             {  
  37.                 break// Connection closed cleanly by peer.  
  38.             }  
  39.             else if (error)  
  40.             {  
  41.                 throw boost::system::system_error(error); // Some other error.  
  42.             }  
  43.             char szMsg[128] = {0};  
  44.             memcpy(szMsg,buf.data(),len);  
  45.             printf("%s\n",szMsg);  
  46.   
  47.             //发送数据  
  48.             socket.write_some(boost::asio::buffer(buf, len), error);  
  49.         }  
  50.     }  
  51.     catch (std::exception& e)  
  52.     {  
  53.         printf(e.what());  
  54.     }  
  55.   
  56.     return 0;  

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Boost.Asio 是一个功能强大的 C++ ,提供了对网络和底层 I/O 操作的跨平台支持。它可以用于实现 TCP 异步通信。 要使用 Boost.Asio 进行 TCP 异步通信,首先需要创建一个 io_context 对象,它负责处理底层的 I/O 操作。然后,创建一个 tcp::socket 对象,用于建立和管理 TCP 连接。接下来,使用异步操作来进行连接、读取和写入数据。 下面是一个简单的示例代码,展示了如何使用 Boost.Asio 进行 TCP 异步通信: ```cpp #include <iostream> #include <boost/asio.hpp> using boost::asio::ip::tcp; class TcpClient { public: TcpClient(boost::asio::io_context& io_context) : io_context_(io_context), socket_(io_context) {} void Connect(const std::string& host, const std::string& port) { tcp::resolver resolver(io_context_); tcp::resolver::results_type endpoints = resolver.resolve(host, port); boost::asio::async_connect(socket_, endpoints, [this](boost::system::error_code ec, tcp::endpoint endpoint) { if (!ec) { std::cout << "Connected to server: " << endpoint << std::endl; Read(); } else { std::cout << "Failed to connect: " << ec.message() << std::endl; } }); } void Read() { boost::asio::async_read(socket_, boost::asio::buffer(data_, max_length), [this](boost::system::error_code ec, std::size_t length) { if (!ec) { std::cout << "Received data: " << std::string(data_, length) << std::endl; Read(); } else { std::cout << "Failed to read data: " << ec.message() << std::endl; } }); } void Write(const std::string& message) { boost::asio::async_write(socket_, boost::asio::buffer(message), [this](boost::system::error_code ec, std::size_t /*length*/) { if (ec) { std::cout << "Failed to write data: " << ec.message() << std::endl; } }); } private: boost::asio::io_context& io_context_; tcp::socket socket_; enum { max_length = 1024 }; char data_[max_length]; }; int main() { boost::asio::io_context io_context; TcpClient client(io_context); client.Connect("localhost", "1234"); // 发送数据示例 client.Write("Hello, server!"); io_context.run(); return 0; } ``` 在上述示例代码中,`TcpClient` 类负责连接服务器、读取和写入数据。`Connect` 方法通过异步连接操作连接到指定的主机和端口,`Read` 方法通过异步读取操作接收服务器发送的数据,`Write` 方法通过异步写入操作向服务器发送数据。 你可以根据自己的需求修改以上示例代码,以适应你的具体应用场景。希望对你有帮助!如果还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

AI算法网奇

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

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

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

打赏作者

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

抵扣说明:

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

余额充值