请对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进行交流
[解决办法]
在收到消息的地方,打印,那部断了