请对socket编程有丰富经验的朋友进来看一个boost.asio通信的问题
我用boost.asio库写了一个server和一个client。功能很简单,client把输入的字符发送出去,server就接收下来显示出来。我现在遇到一个很奇怪的问题,就是偶尔在server端会出现995错误。995错误的意思是
“由于线程退出或应用程序请求,已中止i/o操作”
由于是偶尔出现,所以我很难差到原因。而且是一连接收几十次不出错,然后下一次就突然出错。或者接连几次出错,然后又几十次不出错。
请大家帮我看看是不是有什么地方应该处理的我没处理。
附代码在下面,不过我估计不会有人看的,只希望大家根据自己的经验提出一些可能出现995错误的原因。
公用类:
C/C++ code
server:
C/C++ code
client:
C/C++ code
“由于线程退出或应用程序请求,已中止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