请对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;
}


作者: facat   发布时间: 2011-08-11

是不是几次连续发送的间隔太短了。试着几次发送之间,停顿一下

作者: jjajun   发布时间: 2011-08-11