Asio 没有收到来自远程系统的回复
Asio does not catch reply from remote system
我正在编写一个应该侦听域套接字的客户端。我打开同步连接,进行同步写入,我知道服务器发送了有效响应,因为我在套接字上使用 socat 到 eavesdrop。
除了我的 asio::read()
被调用但从未 returns 任何数据。我传递给它的缓冲区总是空的。这是我的代码:
void operator>>(const vector<unsigned char> input, Socket &socket) {
const size_t size = input.size();
const size_t bytes = asio::write(socket.connection_socket, asio::buffer(input, size));
if (bytes != size) {
const std::error_code ec;
throw std::system_error(ec, fmt::format("Tried to send {0} bytes but sent {1} instead.", size, bytes));
}
string buffer;
asio::read(socket.connection_socket, asio::buffer(buffer));
std::cerr << buffer << std::endl;
}
这些是我用来连接到套接字的属性:
io_service run_loop;
stream_protocol::socket connection_socket;
datagram_protocol::endpoint domain_socket_ep;
Socket
是一个简单的 class,它包装了所有 Asio 代码,其中声明了上面的运算符重载。
asio::read
函数将读取 最多 asio::buffer_size(asio::buffer(buffer))
个字节。在你的情况下 buffer
是空的,所以它最多读取零字节。
Asio 永远不会调整您传递给它的缓冲区的大小,因此您需要将 buffer
调整为您期望接收的最大大小。
此外,asio::read
函数实际读取的字节可能少于输入缓冲区的大小。它读取的实际大小从该函数返回。因此,如果你想 read/write 恰好可以放入缓冲区的字节数,你需要做这样的事情:
void read_to_buffer(asio::ip::tcp::socket& s, asio::buffer buffer) {
size_t read = 0;
size_t n = asio::buffer_size(buffer);
while (read < n) {
read += asio::read(s, buffer + read));
}
}
void write_from_buffer(asio::ip::tcp::socket& s, asio::buffer buffer) {
size_t written = 0;
size_t n = asio::buffer_size(buffer);
while (written < n) {
written += asio::write(s, buffer + written));
}
}
void operator>>(const vector<unsigned char> input, Socket &socket) {
// TODO: convert between host and network byte order
auto& s = socket.connection_socket;
{
const uint32_t size = input.size();
write_from_buffer(s, asio::buffer(&size, sizeof(size));
write_from_buffer(s, asio::buffer(input));
}
{
uint32_t size = 0;
read_to_buffer(s, asio::buffer(&size, sizeof(size)));
string payload(size, 'x');
read_to_buffer(s, asio::buffer(payload));
std::cerr << payload << std::endl;
}
}
我正在编写一个应该侦听域套接字的客户端。我打开同步连接,进行同步写入,我知道服务器发送了有效响应,因为我在套接字上使用 socat 到 eavesdrop。
除了我的 asio::read()
被调用但从未 returns 任何数据。我传递给它的缓冲区总是空的。这是我的代码:
void operator>>(const vector<unsigned char> input, Socket &socket) {
const size_t size = input.size();
const size_t bytes = asio::write(socket.connection_socket, asio::buffer(input, size));
if (bytes != size) {
const std::error_code ec;
throw std::system_error(ec, fmt::format("Tried to send {0} bytes but sent {1} instead.", size, bytes));
}
string buffer;
asio::read(socket.connection_socket, asio::buffer(buffer));
std::cerr << buffer << std::endl;
}
这些是我用来连接到套接字的属性:
io_service run_loop;
stream_protocol::socket connection_socket;
datagram_protocol::endpoint domain_socket_ep;
Socket
是一个简单的 class,它包装了所有 Asio 代码,其中声明了上面的运算符重载。
asio::read
函数将读取 最多 asio::buffer_size(asio::buffer(buffer))
个字节。在你的情况下 buffer
是空的,所以它最多读取零字节。
Asio 永远不会调整您传递给它的缓冲区的大小,因此您需要将 buffer
调整为您期望接收的最大大小。
此外,asio::read
函数实际读取的字节可能少于输入缓冲区的大小。它读取的实际大小从该函数返回。因此,如果你想 read/write 恰好可以放入缓冲区的字节数,你需要做这样的事情:
void read_to_buffer(asio::ip::tcp::socket& s, asio::buffer buffer) {
size_t read = 0;
size_t n = asio::buffer_size(buffer);
while (read < n) {
read += asio::read(s, buffer + read));
}
}
void write_from_buffer(asio::ip::tcp::socket& s, asio::buffer buffer) {
size_t written = 0;
size_t n = asio::buffer_size(buffer);
while (written < n) {
written += asio::write(s, buffer + written));
}
}
void operator>>(const vector<unsigned char> input, Socket &socket) {
// TODO: convert between host and network byte order
auto& s = socket.connection_socket;
{
const uint32_t size = input.size();
write_from_buffer(s, asio::buffer(&size, sizeof(size));
write_from_buffer(s, asio::buffer(input));
}
{
uint32_t size = 0;
read_to_buffer(s, asio::buffer(&size, sizeof(size)));
string payload(size, 'x');
read_to_buffer(s, asio::buffer(payload));
std::cerr << payload << std::endl;
}
}