服务器启动并接受连接,即使连接了10个以上的所有客户端,也会发送一条消息,但是没有响应。
读写功能使用接收到的客户帐户的索引并对其进行处理。因此,标头中还有一个附加参数。
我们接受连接并将其编号传递到标题,然后使用该编号的套接字进行连接。
#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <clocale>
#include <vector>
#include <conio.h>
using namespace boost::asio;
using namespace std;
class tcp_server
{
private:
io_service service;
int port;
enum { buff_size = 1024 };
ip::tcp::endpoint endpoint;
ip::tcp::acceptor acceptor;
int countClients = 0;
int accept_i = 0;
struct client
{
ip::tcp::socket sock;
char buff[buff_size] = { };
};
vector<client> clients;
public:
tcp_server(io_service& service, int port) : service(), acceptor(service), endpoint(ip::tcp::v4(), port)
{
this->port;
acceptor.open(endpoint.protocol());
acceptor.set_option(ip::tcp::acceptor::reuse_address(true));
acceptor.bind(endpoint);
acceptor.listen();
clients.reserve(10);
}
void start()
{
start_service_in_thread();
}
void start_service_in_thread()
{
for (int i = 0; i < 10; ++i)
boost::thread(service_func_for_thread);
for (int i = 0; i < 10; ++i)
{
boost::thread(acceptor_func_for_thread);
accept_i++;
}
}
void service_func_for_thread()
{
service.run();
}
void accept_handler(const boost::system::error_code& error)
{
if (!error)
{
countClients++;
do_read_this(countClients - 1);
}
else
{
cout << "Acceptor error\n";
cout << error.message() << endl;
}
}
void acceptor_func_for_thread()
{
acceptor.async_accept(
clients[accept_i].sock,
boost::bind(&tcp_server::accept_handler, this, boost::asio::placeholders::error)
);
}
void do_read_this(int thisClientIndex)
{
clients[thisClientIndex].sock.async_read_some(
buffer(clients[thisClientIndex].buff),
boost::bind(&tcp_server::read_handler,
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred,
thisClientIndex)
);
}
void read_handler(const boost::system::error_code& error, size_t bytes_transferred, int thisClientIndex)
{
if (!error)
{
clients[thisClientIndex].sock.async_write_some(
buffer(clients[thisClientIndex].buff),
boost::bind(&tcp_server::write_handler,
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred,
thisClientIndex)
);
}
else
{
cout << "Error reading from socket\n";
cout << error.message() << endl;
}
}
void write_handler(const boost::system::error_code& error, size_t bytes_transferred, int thisClientIndex)
{
if (!error)
{
do_read_this(thisClientIndex);
}
else
{
cout << "Error write in socket\n";
cout << error.message() << endl;
}
}
};
int main(int argc, char *argv[])
{
try
{
setlocale(LC_ALL, "Rus");
io_service service;
tcp_server* server = new tcp_server{ service, 5000 };
server->start();
service.run();
}
catch (exception& ex)
{
cout << "Exception: " << ex.what();
}
return 0;
}
客户端连接到服务器,并且当它发送连接时,没有收到响应。 请帮忙。
答案 0 :(得分:0)
service.run();
中的 main
无关,因此会立即返回,因此main
返回会导致程序结束。
此处无需创建后台线程。
(再次)您将创建一个临时对象boost::thread
,该对象立即超出范围。而且,除非指定了BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
,否则最终将导致一堆分离的线程。
答案 1 :(得分:0)
当io_service::run()
方法无事可做时,它会返回。
您应该
post()
在调用io_service
之前至少要执行run()
的一项任务,
或使用io_service::work
io_service service;
boost::asio::io_service::work work(service);
后者需要调用service.stop()
才能导致run()
退出,否则它将永久运行。
但是请注意:在异步应用程序中,您实际上不需要两个io_service
或任何线程。