Boost Asio Socket issue
Boost Asio Socket issue
我是Boost的新手。我正在开发一个小服务器。当客户端向我的服务器发送消息时,我有一个问题。我的服务器调用函数读取套接字两次
这是我的客户端类
中的代码void ClientManager::ToRecv(void)
{
this->_socket.async_read_some(boost::asio::buffer(_buffer),
_strand.wrap(boost::bind(&ClientManager::HandleRead, this, boost::asio::placeholders::error))
);
}
void ClientManager::HandleRead(boost::system::error_code const & error)
{
_mutex.lock();
std::cout << boost::this_thread::get_id() << " client->HandleRead()" << std::endl;
for (unsigned int i = 0; i < _buffer.size(); ++i)
{
std::cout << _buffer[i]; // I display the message
}
std::cout << std::endl;
_mutex.unlock();
this->ToRecv();
}
当客户端连接时,我调用start函数。下面是我启动服务器时在控制台中显示的内容:
我创建了3个线程
Server Connect
[004FE200] Thread Start
[004FE238] Thread Start
[004FE7C8] Thread Start
,这是当我连接一个putty客户端到我的服务器
[004FE7C8] acceptor->NewClient()
[004FE7C8] client->Start()
当客户端发送"hello world"时,我的服务器显示的是这个
[004FE238] client->HandleRead()
hello world
[004FE7C8] client->HandleRead()
llo world
我不知道_buffer类型是什么,但它应该看起来像这样,注意bytes_transferred
。
void ClientManager::HandleRead(boost::system::error_code const & error, size_t bytes_transferred)
{
_mutex.lock();
std::cout << boost::this_thread::get_id() << " client->HandleRead()" << std::endl;
for (unsigned int i = 0; i < bytes_transferred; ++i)
{
std::cout << _buffer[i]; // I display the message
}
std::cout << std::endl;
_mutex.unlock();
this->ToRecv();
}
互斥锁是怎么回事?真的有必要吗?
我会这样写:
void ClientManager::HandleRead(boost::system::error_code const & error, size_t bytes_transferred)
{
std::cout << boost::this_thread::get_id() << " client->HandleRead()" << std::endl;
std::copy(_buffer.begin(), _buffer.begin() + bytes_transferred, std::ostream_iterator<char>(std::cout));
std::cout << std::endl;
this->ToRecv();
}
现在,您可能会看到(并且从您下面的评论中已经看到)的事实是,HandleRead()
将被多次调用,仅包含部分消息。如果你在调用read
函数之前知道消息的大小,你可以使用组合函数async_read()代替。这是boost::asio
命名空间中的自由函数。
我猜您在某处将_buffer
初始化为"Hello World"。
调用socket::async_read_some
不能保证在调用完成处理程序之前已经读取了所有的数据。您可以使用asio
名称空间中的组合自由函数来完成此操作。
因此,可能发生的情况是,您在第一次调用处理程序时获得部分消息,而在第二次调用中获得其余消息。然而,如果缓冲区已经初始化,它将看起来像你收到了两次消息。
更改这一行,同时传递传输字节数的占位符:
_strand.wrap(
boost::bind(
&ClientManager::HandleRead,
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)));
然后适当更改HandleRead()
函数:
void ClientManager::HandleRead(
boost::system::error_code const & error,
size_t bytes_transferred) // Add bytes_transferred
{
_mutex.lock();
std::cout << boost::this_thread::get_id() << " client->HandleRead()" << std::endl;
// Then -- check the buffer up to the number of bytes transferred:
for (unsigned int i = 0; i < bytes_transferred; ++i)
{
std::cout << _buffer[i]; // I display the message
}
std::cout << std::endl;
_mutex.unlock();
this->ToRecv();
}
相关文章:
- Seg Fault Issue C++ (file IO / getline)
- Issue with WriteProcessMemory
- std::partition segfault issue
- C/C++:socket() 创建在循环中失败,打开的文件太多
- 不将数据 socket.io c++(客户端)发送到 nodejs(服务器)socket.io
- VSCode C/C++ Intellisense issue: Undefined identifiers (Linu
- 通过 Tor 服务C++ socket.io 客户端
- OpenGL glBufferSubData Offset issue
- boost::property_tree XML issue
- qt QWidget::closeEvent link issue
- QT 和 JIRA Rest API: /rest/api/2/issue/createmeta 意外返回韩语的 iss
- 操作系统 (Linux) 在使用 boost::asio::generic::raw_protocol::socket
- Crypto++ GetModulus() issue
- Make zmqpp::socket::connect a std::future
- 为什么可以重复使用这个boost::asio::tcp::socket
- 如何从 boost::asio::ssl::stream<boost::asio::ip::tcp::socket> 获取本机套接字文件描述器?
- Socket.io客户端C++,从Socket.on获取数组
- 调用socket.remote_endpoint(提升 asio 库)线程安全性
- Boost Asio Socket issue
- C++ win32 async socket client send() issue