神秘的200连接从何而来?
嘿伙计们,我是异步编程的新手,这可能是一个愚蠢的问题,但它确实让我发疯了!
这是代码(它只是对 boost.asio 的示例进行了一些修改):
server.cpp:
class tcp_server
{
public:
tcp_server(boost::asio::io_service& io_service)
: acceptor_(io_service, tcp::endpoint(tcp::v4(), 10000)),limit(0)
{
start_accept();
}
private:
void start_accept()
{
while(1)
{
if(limit <= 10)
{
std::cout << limit << std::endl;
break;
}
}
tcp::socket* socket = new tcp::socket(acceptor_.io_service());
acceptor_.async_accept(*socket,
boost::bind(&tcp_server::handle_accept, this, boost::asio::placeholders::error));
}
void handle_accept(const boost::system::error_code& error)
{
if (!error)
{
++limit ;
start_accept();
}
}
tcp::acceptor acceptor_;
int limit;
};
int main()
{
try
{
boost::asio::io_service io_service;
tcp_server server(io_service);
io_service.run();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
client.cpp:
int main(int argc, char* argv[])
{
int i = 0;
while(1)
{
try
{
boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
tcp::resolver::query query("127.0.0.1", "10000");
tcp::resolver::iterator endpoint_iterator =resolver.resolve(query);
tcp::endpoint endpoint = *endpoint_iterator;
tcp::socket socket(io_service);
socket.close();
socket.connect(endpoint);
std::cout << i++ << std::endl;
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}
return 0;
}
我只是想限制服务器接受 10 个客户端。 然而,客户端在计算出“惊人”的210(不多也不少)个连续数字后,就抛出了错误信息。 发生了什么事??
Hey guys, i'm a newbie to async-programming, this is probably a stupid question, but it indeed drove me crazy!!
Here's the code (it just modified a bit from boost.asio's sample):
server.cpp:
class tcp_server
{
public:
tcp_server(boost::asio::io_service& io_service)
: acceptor_(io_service, tcp::endpoint(tcp::v4(), 10000)),limit(0)
{
start_accept();
}
private:
void start_accept()
{
while(1)
{
if(limit <= 10)
{
std::cout << limit << std::endl;
break;
}
}
tcp::socket* socket = new tcp::socket(acceptor_.io_service());
acceptor_.async_accept(*socket,
boost::bind(&tcp_server::handle_accept, this, boost::asio::placeholders::error));
}
void handle_accept(const boost::system::error_code& error)
{
if (!error)
{
++limit ;
start_accept();
}
}
tcp::acceptor acceptor_;
int limit;
};
int main()
{
try
{
boost::asio::io_service io_service;
tcp_server server(io_service);
io_service.run();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
client.cpp:
int main(int argc, char* argv[])
{
int i = 0;
while(1)
{
try
{
boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
tcp::resolver::query query("127.0.0.1", "10000");
tcp::resolver::iterator endpoint_iterator =resolver.resolve(query);
tcp::endpoint endpoint = *endpoint_iterator;
tcp::socket socket(io_service);
socket.close();
socket.connect(endpoint);
std::cout << i++ << std::endl;
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}
return 0;
}
I just wanna limit server to accept 10 client.
However, client cout the error information after it cout "amazing" 210 (never more or less) continuous numbers.
What happend??
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我对 server.cpp 做了一些更改。首先在构造函数上重新配置acceptor_。删除了 while 循环,添加了acceptor_.close();
我想,默认接受器可以一次 async_accept 200 个连接事件。您可以在无限循环中从客户端打开一个套接字并关闭它。结果你打开和关闭一个连接 200 次,但它仍然是 1 个连接,1 个套接字。
通过调用listen(1)将其上限设置为1,将强制接受者触发事件。您增加计数,然后客户端关闭连接。这样您就可以正确计算每个连接事件。
最后说明: 异步 io 使用 1 个线程来处理连接事件、检索数据等...因此,不需要使用互斥体。
I've changed server.cpp a bit. First reconfigured acceptor_ on constructor. Removed while loop, added acceptor_.close();
I suppose, default acceptor can async_accept 200 connection events at a time. You open a socket and close it from the client side in an infinite loop. As a result you open and close a connection 200 times, but it is still 1 connection, 1 socket.
Capping it to 1 by calling listen(1), would force the acceptor to fire an event. You increase the count, then client closes the connection. This way you correctly count each connection event.
Last note: async io uses 1 thread to process connection events, retrieved data etc... Thus, use of mutexes are not necessary.