boost::asio客户端如果连接不上服务端,那么如何处理呢?

时间:2022-09-08 22:39:06

boost::asio中的几个小问题

看了罗。。的那本boost的 asio的哪一张,讲的很简单

难以应付我 的问题啊

一。
只要先运行客户端,服务端不开启,那么立即挂了,原因是connect的问题,如果克服呢,当服务端不在的时候,客户端自己处理一下。

网上的例子多半是这个,但是没有说如何来解决这个问题啊。

我把我的客户端的代码在这里,(还有,如果客户端断开,又如何处理,网上的例子大多是让人入门的,

像这类的问题,太少了)

Client端:

struct CHelloWorld_Client{ 
CHelloWorld_Client(io_service &iosev) 
:m_iosev(iosev) 



void start() 


//tcp类下(asio::ip::tcp)
ip::tcp::endpoint ep(ip::address_v4::from_string("127.0.0.1"), 6555); 
shared_ptr<ip::tcp::socket> psocket(new ip::tcp::socket(m_iosev));
psocket->connect(ep); //连接远方
shared_ptr<string> pstr(new string("helllxxxx"));
psocket->async_write_some(buffer(*pstr),bind( &CHelloWorld_Client::write_handler, this, pstr, _1  ) ); 



// 异步写操作完成后write_handler触发 
void write_handler(shared_ptr<string> pstr, error_code ec) 

if(ec) 
std::cout<< "发送失败!" << std::endl; 
else 
std::cout<< *pstr << " 已发送" << std::endl; 


private: 
io_service &m_iosev; 

}; 



二、服务端的问题

helllxxxx 这是客户端发送的数据,为什么服务端只收到一个字母,很多都接受不了,而且服务端死住了。



struct CHelloWorld_Server{ 
CHelloWorld_Server(io_service &iosev) 
:m_iosev(iosev),m_acceptor(iosev, ip::tcp::endpoint(ip::tcp::v4(), 6555)) 




void start() 

// 开始等待连接(非阻塞) 
shared_ptr<ip::tcp::socket> psocket(new ip::tcp::socket(m_iosev)); 
// 触发的事件只有error_code参数,所以用boost::bind把socket绑定进去 
m_acceptor.async_accept(*psocket, 
bind(&CHelloWorld_Server::accept_handler, this, psocket, _1) 
); 



// 有客户端连接时accept_handler触发 
void accept_handler(boost::shared_ptr<ip::tcp::socket> psocket, error_code ec) 

memset(data,0,10);
if(ec) return; 
// 继续等待连接 
start(); 
// 显示远程IP 
std::cout << psocket->remote_endpoint().address() << std::endl; 


//改成接受的信息为:
psocket->async_read_some(buffer(data,3), 
bind(&CHelloWorld_Server::read_handler, this, data, _1) 
); 



// 异步写操作完成后read_handler触发 
void read_handler(char *pstr, error_code ec) 

if(ec) 
std::cout<< "接受失败!" << std::endl; 
else 
{
std::cout<< "收到的数据:"<<*pstr<<std::endl; 
}



private: 
io_service &m_iosev; 

ip::tcp::acceptor  m_acceptor;

char data[300];

}; 

有使用经验的,请分享一下,谢谢了啊。

英文不行,呵呵


7 个解决方案

#1


别藏着经验、

哈哈 

#2


服务端想收全信息 要在read_handler中更具应用层报文判断是否收全一个报文
未接受完的话

    void read_handler(char *pstr, error_code ec) 
    { 
        if(ec) 
            std::cout<< "接受失败!" << std::endl; 
        else 
        {
            if not recv a whole package
            {
                psocket->async_read_some(buffer(data + w_pos,3), 
                    bind(&CHelloWorld_Server::read_handler, this, data, _1) 
                    ); 
            }
            else
            {
                do something...
            }
            
        }
    }
 

另外什么叫客户端自己处理一下 如果是服务器组的话遍历服务器列表吗

#3


就是说,如果断开了

那么客户端得用户一个提示啊,

对吧,链接上了,也得给一个提示啊



引用 2 楼  的回复:
服务端想收全信息 要在read_handler中更具应用层报文判断是否收全一个报文
未接受完的话
C/C++ code

    void read_handler(char *pstr, error_code ec) 
    { 
        if(ec) 
            std::cout<< "接受失败!" << std::endl; 
        else 
 ……

#4


如你说所,客户段就发几十个字符过来

服务端显然不知道何谓一个完整的报文,如何判断?

另外:

buffer(data + w_pos,3),

w_pos是什么??

还有这个3,是我随机写的,据说 这个数字得小一点,否则程序非刮不可。








引用 2 楼  的回复:
服务端想收全信息 要在read_handler中更具应用层报文判断是否收全一个报文
未接受完的话
C/C++ code

    void read_handler(char *pstr, error_code ec) 
    { 
        if(ec) 
            std::cout<< "接受失败!" << std::endl; 
        else 
 ……

#5


还有,又在read-hander中调用 read_some,不会用问题吗??

accept中已经调用了一次啊




引用 2 楼  的回复:
服务端想收全信息 要在read_handler中更具应用层报文判断是否收全一个报文
未接受完的话
C/C++ code

    void read_handler(char *pstr, error_code ec) 
    { 
        if(ec) 
            std::cout<< "接受失败!" << std::endl; 
        else 
 ……

#6


看下boost::asio的聊天室chat的例子吧 里面有比较完整的客户端服务器代码

#7



void connection::handle_read( const boost::system::error_code& ec, std::size_t bytes_transferred )
{
if (!ec)
{
DisplayMem((unsigned char*)&recv_buffer_[0],bytes_transferred,"read data from client:");
buffer_packager_.push_buffer(&recv_buffer_[0],bytes_transferred);

//process buffer
while(!buffer_packager_.is_empty())
process_buffer(buffer_packager_.pop_buffer());

socket_.async_read_some(boost::asio::buffer(recv_buffer_),
strand_.wrap(boost::bind(
&connection::handle_read,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)
)
);
}
else
{
//write(TraceFlage,"read Data  Erro : socket id %d  ErroCode %s",id_,ec.message().c_str());
shut_down();
}
}


这个是我工程里面的一段代码 一般要通讯业务层来确定一个报文是否收全 这和你的应用层协议有关 readsome在用的时候传一个std::size_t bytes_transferred参数表示接受到的字节数

#1


别藏着经验、

哈哈 

#2


服务端想收全信息 要在read_handler中更具应用层报文判断是否收全一个报文
未接受完的话

    void read_handler(char *pstr, error_code ec) 
    { 
        if(ec) 
            std::cout<< "接受失败!" << std::endl; 
        else 
        {
            if not recv a whole package
            {
                psocket->async_read_some(buffer(data + w_pos,3), 
                    bind(&CHelloWorld_Server::read_handler, this, data, _1) 
                    ); 
            }
            else
            {
                do something...
            }
            
        }
    }
 

另外什么叫客户端自己处理一下 如果是服务器组的话遍历服务器列表吗

#3


就是说,如果断开了

那么客户端得用户一个提示啊,

对吧,链接上了,也得给一个提示啊



引用 2 楼  的回复:
服务端想收全信息 要在read_handler中更具应用层报文判断是否收全一个报文
未接受完的话
C/C++ code

    void read_handler(char *pstr, error_code ec) 
    { 
        if(ec) 
            std::cout<< "接受失败!" << std::endl; 
        else 
 ……

#4


如你说所,客户段就发几十个字符过来

服务端显然不知道何谓一个完整的报文,如何判断?

另外:

buffer(data + w_pos,3),

w_pos是什么??

还有这个3,是我随机写的,据说 这个数字得小一点,否则程序非刮不可。








引用 2 楼  的回复:
服务端想收全信息 要在read_handler中更具应用层报文判断是否收全一个报文
未接受完的话
C/C++ code

    void read_handler(char *pstr, error_code ec) 
    { 
        if(ec) 
            std::cout<< "接受失败!" << std::endl; 
        else 
 ……

#5


还有,又在read-hander中调用 read_some,不会用问题吗??

accept中已经调用了一次啊




引用 2 楼  的回复:
服务端想收全信息 要在read_handler中更具应用层报文判断是否收全一个报文
未接受完的话
C/C++ code

    void read_handler(char *pstr, error_code ec) 
    { 
        if(ec) 
            std::cout<< "接受失败!" << std::endl; 
        else 
 ……

#6


看下boost::asio的聊天室chat的例子吧 里面有比较完整的客户端服务器代码

#7



void connection::handle_read( const boost::system::error_code& ec, std::size_t bytes_transferred )
{
if (!ec)
{
DisplayMem((unsigned char*)&recv_buffer_[0],bytes_transferred,"read data from client:");
buffer_packager_.push_buffer(&recv_buffer_[0],bytes_transferred);

//process buffer
while(!buffer_packager_.is_empty())
process_buffer(buffer_packager_.pop_buffer());

socket_.async_read_some(boost::asio::buffer(recv_buffer_),
strand_.wrap(boost::bind(
&connection::handle_read,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)
)
);
}
else
{
//write(TraceFlage,"read Data  Erro : socket id %d  ErroCode %s",id_,ec.message().c_str());
shut_down();
}
}


这个是我工程里面的一段代码 一般要通讯业务层来确定一个报文是否收全 这和你的应用层协议有关 readsome在用的时候传一个std::size_t bytes_transferred参数表示接受到的字节数