首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

请对socket编程有丰富经验的朋友进来看一个boost.asio通信的有关问题

2012-04-09 
请对socket编程有丰富经验的朋友进来看一个boost.asio通信的问题我用boost.asio库写了一个server和一个cli

请对socket编程有丰富经验的朋友进来看一个boost.asio通信的问题
我用boost.asio库写了一个server和一个client。功能很简单,client把输入的字符发送出去,server就接收下来显示出来。我现在遇到一个很奇怪的问题,就是偶尔在server端会出现995错误。995错误的意思是
“由于线程退出或应用程序请求,已中止i/o操作”

由于是偶尔出现,所以我很难差到原因。而且是一连接收几十次不出错,然后下一次就突然出错。或者接连几次出错,然后又几十次不出错。

请大家帮我看看是不是有什么地方应该处理的我没处理。

附代码在下面,不过我估计不会有人看的,只希望大家根据自己的经验提出一些可能出现995错误的原因。

公用类:

C/C++ code
#ifndef __TCP_ECHO_CONNECTION#define __TCP_ECHO_CONNECTION#include <boost/asio.hpp>class tcp_echo_connection{public:    tcp_echo_connection(boost::asio::io_service& _io_srvice);    //tcp_echo_connection(){};    boost::asio::ip::tcp::socket& getsocket();    tcp_echo_connection* getthis()    {        return this;    }private:    boost::asio::ip::tcp::socket _socket;};tcp_echo_connection::tcp_echo_connection(boost::asio::io_service& _io_srvice) :        _socket(_io_srvice){}boost::asio::ip::tcp::socket& tcp_echo_connection::getsocket(){    return _socket;}#endif



server:
C/C++ code
#define _WIN32_WINNT  0x0600#define _GLIBCXX_DEBUG#define BOOST_ASIO_ENABLE_HANDLER_TRACKING#include <iostream>#include <string>#include <boost/asio.hpp>#include <list>#include <boost/shared_ptr.hpp>#include <boost/shared_array.hpp>#include <boost/bind.hpp>#include "tcp_echo_connection.h"using namespace std;class tcp_echo_connection;class tcp_echo_server;class tcp_echo_server{public:    tcp_echo_server(boost::asio::io_service& _io_srvice,            boost::asio::ip::tcp::endpoint &_endpoint);private:    void start_acceptor(boost::asio::io_service& _io_srvice);    void action(boost::shared_ptr<tcp_echo_connection> tcp_conn,            const boost::system::error_code& error);    void asy_read();    void asy_read_handle(boost::shared_array<char> revdata,            const boost::system::error_code& error, // Result of operation.            std::size_t bytes_transferred // Number of bytes read.            );private:    boost::asio::ip::tcp::acceptor _acceptor;    const static int MAX_ACCEPTOR = 5;    static int acceptor_count;};int tcp_echo_server::acceptor_count = 0;void tcp_echo_server::start_acceptor(boost::asio::io_service& _io_srvice){    acceptor_count++;    boost::shared_ptr<tcp_echo_connection> ptr(            new tcp_echo_connection(_io_srvice));    cout << "start accepting" << endl;    cout << "current accepting count: " << acceptor_count << endl;    _acceptor.async_accept(            ptr->getsocket(),            boost::bind(&tcp_echo_server::action, this, ptr,                    boost::asio::placeholders::error));}tcp_echo_server::tcp_echo_server(boost::asio::io_service& _io_srvice,        boost::asio::ip::tcp::endpoint &_endpoint) :        _acceptor(_io_srvice, _endpoint){    start_acceptor(_io_srvice);}void tcp_echo_server::action(boost::shared_ptr<tcp_echo_connection> tcp_conn,        const boost::system::error_code& error){    try    {        if (!error)        {            boost::asio::ip::tcp::socket& t_socket = tcp_conn->getsocket();            boost::shared_array<char> revdata(new char[128]);            cout << "starting receiving" << endl;            t_socket.async_read_some(                    boost::asio::mutable_buffers_1(revdata.get(), 128),                    boost::bind(&tcp_echo_server::asy_read_handle, this,                            revdata, boost::asio::placeholders::error,                            boost::asio::placeholders::bytes_transferred));        }        else        {            throw boost::system::error_code(error);        }    } catch (std::exception &e)    {        std::cerr << e.what() << std::endl;        acceptor_count--;    } catch (boost::system::error_code& e)    {        cout << "exception catch" << endl;        cout << e.message() << endl;        acceptor_count--;    }    for (int i = 0; i < MAX_ACCEPTOR - acceptor_count; i++)    {        std::cout << "start another" << std::endl;        this->start_acceptor(_acceptor.get_io_service());    }}void tcp_echo_server::asy_read_handle(boost::shared_array<char> revdata,        const boost::system::error_code& error, // Result of operation.        std::size_t bytes_transferred // Number of bytes read.        ){    try    {        if (error)        {            cout << "error:" << error << endl;            throw boost::system::error_code(error);        }        else        {            cout << "str is" << endl;            cout << revdata.get() << endl;            acceptor_count--;            for (int i = 0; i < MAX_ACCEPTOR - acceptor_count; i++)            {                std::cout << "start another" << std::endl;                this->start_acceptor(_acceptor.get_io_service());            }            //std::cout << "start another" << std::endl;            //this->start_acceptor(_acceptor.get_io_service());        }    } catch (std::exception &e)    {        cout << "exception catch" << endl;        cout << e.what() << endl;        acceptor_count--;    } catch (boost::system::error_code& e)    {        cout << "exception catch" << endl;        cout << e.message() << endl;        acceptor_count--;    }}int main(){    try    {        boost::asio::io_service io_service;        boost::asio::ip::tcp::resolver _resolver(io_service);        boost::asio::ip::tcp::resolver::query _query("localhost", "13");        boost::asio::ip::tcp::resolver::iterator ite(_resolver.resolve(_query));        boost::asio::ip::tcp::endpoint _endpoint(*ite);        std::cout << _endpoint << std::endl;        tcp_echo_server myserver(io_service, _endpoint);        io_service.run();    } catch (std::exception& e)    {        std::cerr << e.what() << std::endl;    }    return 0;} 



client:
C/C++ code
#define _WIN32_WINNT  0x0600#include <tcp_echo_connection.h>#include <boost/asio.hpp>#include <boost/shared_ptr.hpp>#include <boost/bind.hpp>#include <string>using namespace std;using namespace boost::asio::ip;using namespace boost::asio;using namespace boost;class tcp_echo_client;class tcp_echo_client{public:    explicit tcp_echo_client(io_service& _ioservice);private:    io_service& m_io_service;    void start_asyconnection();    void start_syconnection();    void action(shared_ptr<tcp_echo_connection> tcp_con,            const boost::system::error_code &_err);    void asy_write_handle(const boost::system::error_code& error, // Result of operation.            std::size_t bytes_transferred // Number of bytes written.            );};tcp_echo_client::tcp_echo_client(io_service &_ioservice) :        m_io_service(_ioservice){    while (1)        start_syconnection();}void tcp_echo_client::start_asyconnection(){    shared_ptr<tcp_echo_connection> tcp_con(            new tcp_echo_connection(m_io_service)); //,tcp::endpoint(tcp::v4(),13));    tcp::socket& t_socket = tcp_con->getsocket();    tcp::resolver _resolver(m_io_service);    tcp::resolver::query _query("localhost", "13");    tcp::resolver::iterator ite(_resolver.resolve(_query));    t_socket.async_connect(            *ite,            boost::bind(&tcp_echo_client::action, this, tcp_con,                    boost::asio::placeholders::error));}void tcp_echo_client::start_syconnection(){    shared_ptr<tcp_echo_connection> tcp_con(            new tcp_echo_connection(m_io_service)); //,tcp::endpoint(tcp::v4(),13));    tcp::socket& t_socket = tcp_con->getsocket();    tcp::resolver _resolver(m_io_service);    tcp::resolver::query _query("localhost", "13");    tcp::resolver::iterator ite(_resolver.resolve(_query));    string datastr;    cout << "input something" << endl;    getline(cin, datastr, '\n');    t_socket.connect(*ite);    boost::system::error_code _err;    try    {        cout << "send : " << datastr.c_str() << endl;        t_socket.write_some(                boost::asio::buffer(datastr.c_str(), datastr.size() + 1), _err);        if (_err)        {            throw boost::system::error_code(_err);        }    } catch (std::exception &e)    {        cerr << e.what() << endl;    } catch (boost::system::error_code &e)    {        cerr << e.message() << endl;    }}void tcp_echo_client::action(shared_ptr<tcp_echo_connection> tcp_con,        const boost::system::error_code &_err){    tcp::socket& t_socket = tcp_con->getsocket();    cout << "input something" << endl;    string inputstr("jh");    cout << "take action" << endl;    try    {        if (!_err)        {            size_t writedata;            t_socket.async_write_some(                    asio::buffer(inputstr.c_str(), inputstr.size()),                    boost::bind(&tcp_echo_client::asy_write_handle, this,                            boost::asio::placeholders::error,                            boost::asio::placeholders::bytes_transferred));            cout << "write " << writedata << endl;        }        else        {            throw boost::system::system_error(_err);            //throw _err;        }    } catch (boost::system::error_code &e)    {        cerr << e.message() << endl;    }    start_asyconnection();}void tcp_echo_client::asy_write_handle(const boost::system::error_code& error, // Result of operation.        std::size_t bytes_transferred // Number of bytes written.        ){}int main(){    boost::asio::io_service myioservice;    try    {        tcp_echo_client a(myioservice);        myioservice.run();        while (1)            ;    } catch (std::exception &e)    {        cout << e.what() << endl;    } catch (boost::system::error_code &e)    {        cerr << e.message() << endl;    }    return 0;} 



[解决办法]
是不是几次连续发送的间隔太短了。试着几次发送之间,停顿一下
[解决办法]
看了你的程序,我也是菜鸟,我有几个疑问

你的服务器是异步的,acceptor之后的回调函数,你用了一个异步读,但是回调函数你又建立一个acceptor,没必要吧!程序用一个acceptor,然后每次建立一个socket即可!
[解决办法]
我看了你的程序,先自我总结一下。我要向你学习,你写的很规整。
1、你先这样调试一下,你在客户端发送完数据。sleep一下。最好发送字节数相同,方便调试
2、最有可能的就是接收的服务端的接收字节的原因。我之前也遇到这个原因


如果有什么不懂的可以加入这个群150712146进行交流
[解决办法]
在收到消息的地方,打印,那部断了

热点排行