asio 套接字,在分隔符处拆分传入数据?
asio socket, split incoming data at a delimitator?
我正在用 C++ 从 asio 套接字读取数据。
我需要将传入数据解析为 json。为此,我需要获得一个 json 字符串条目。我正在添加一个字符';'在 json 字符串的末尾,现在我需要在读取时在该字符处拆分。我正在尝试这个:
int main()
{
asio::io_service service;
asio::ip::tcp::endpoint endpoint(asio::ip::address::from_string("127.0.0.1"), 4444);
asio::ip::tcp::socket socket(service);
std::cout << "[Client] Connecting to server..." << std::endl;
socket.connect(endpoint);
std::cout << "[Client] Connection successful" << std::endl;
while (true)
{
std::string str;
str.resize(2048);
asio::read(socket, asio::buffer(str));
std::string parsed;
std::stringstream input_stringstream(str);
if (std::getline(input_stringstream, parsed, ';'))
{
std::cout << parsed << std::endl;
std::cout<<std::endl;
}
}
}
但它给了我字符串的随机部分。
完整消息是:(用于测试,未 json 格式化)
this is the message in full, no more no less ;
我得到:
full, no more no less
this is the message in full, no more no less
ull, no more no less
is is the message in full, no more no less
l, no more no less
is the message in full, no more no less
no more no less
我哪里错了?
谢谢!
我会使用 read_until
:
#include <boost/asio.hpp>
#include <iostream>
#include <iomanip>
namespace asio = boost::asio;
using asio::ip::tcp;
int main()
{
asio::io_service service;
tcp::socket socket(service);
socket.connect({{}, 4444});
std::string str;
while (auto n = asio::read_until(socket, asio::dynamic_buffer(str), ';')) {
std::cout << std::quoted(std::string_view(str).substr(0, n - 1)) << std::endl;
str.erase(0, n);
}
}
例如示例服务器:
paste -sd\; /etc/dictionaries-common/words | netcat -l -p 4444
输出为:
"A"
"A's"
"AMD"
"AMD's"
"AOL"
"AOL's"
"Aachen"
"Aachen's"
"Aaliyah"
"Aaliyah's"
"Aaron"
"Aaron's"
"Abbas"
"Abbas's"
"Aberdeen's"
...
"zucchinis"
"zwieback"
"zwieback's"
"zygote"
"zygote's"
"zygotes"
"Ångström"
"Ångström's"
"éclair"
"éclair's"
"éclairs"
"éclat"
"éclat's"
"élan"
"élan's"
"émigré"
"émigré's"
"émigrés"
"épée"
"épée's"
"épées"
"étude"
"étude's"
其他提示
您可以使用任何动态缓冲区。这是 streambuf
:
for (asio::streambuf buf; auto n = asio::read_until(socket, buf, ';');) {
std::cout << std::string_view(
asio::buffer_cast<char const*>(buf.data()), n)
<< std::endl;
buf.consume(n);
}
或者,混合,显示 dynamic_string_buffer
模拟与 streambuf
相同的概念:
std::string str;
for (auto buf = asio::dynamic_buffer(str);
auto n = asio::read_until(socket, buf, ';');) {
std::cout << std::string_view(
asio::buffer_cast<char const*>(buf.data()), n)
<< std::endl;
buf.consume(n);
}
或者:
std::vector<unsigned char> vec;
for (auto buf = asio::dynamic_buffer(vec);
auto n = asio::read_until(socket, buf, ';');) {
std::cout << std::string_view(
asio::buffer_cast<char const*>(buf.data()), n)
<< std::endl;
buf.consume(n);
}
我正在用 C++ 从 asio 套接字读取数据。
我需要将传入数据解析为 json。为此,我需要获得一个 json 字符串条目。我正在添加一个字符';'在 json 字符串的末尾,现在我需要在读取时在该字符处拆分。我正在尝试这个:
int main()
{
asio::io_service service;
asio::ip::tcp::endpoint endpoint(asio::ip::address::from_string("127.0.0.1"), 4444);
asio::ip::tcp::socket socket(service);
std::cout << "[Client] Connecting to server..." << std::endl;
socket.connect(endpoint);
std::cout << "[Client] Connection successful" << std::endl;
while (true)
{
std::string str;
str.resize(2048);
asio::read(socket, asio::buffer(str));
std::string parsed;
std::stringstream input_stringstream(str);
if (std::getline(input_stringstream, parsed, ';'))
{
std::cout << parsed << std::endl;
std::cout<<std::endl;
}
}
}
但它给了我字符串的随机部分。
完整消息是:(用于测试,未 json 格式化)
this is the message in full, no more no less ;
我得到:
full, no more no less
this is the message in full, no more no less
ull, no more no less
is is the message in full, no more no less
l, no more no less
is the message in full, no more no less
no more no less
我哪里错了?
谢谢!
我会使用 read_until
:
#include <boost/asio.hpp>
#include <iostream>
#include <iomanip>
namespace asio = boost::asio;
using asio::ip::tcp;
int main()
{
asio::io_service service;
tcp::socket socket(service);
socket.connect({{}, 4444});
std::string str;
while (auto n = asio::read_until(socket, asio::dynamic_buffer(str), ';')) {
std::cout << std::quoted(std::string_view(str).substr(0, n - 1)) << std::endl;
str.erase(0, n);
}
}
例如示例服务器:
paste -sd\; /etc/dictionaries-common/words | netcat -l -p 4444
输出为:
"A"
"A's"
"AMD"
"AMD's"
"AOL"
"AOL's"
"Aachen"
"Aachen's"
"Aaliyah"
"Aaliyah's"
"Aaron"
"Aaron's"
"Abbas"
"Abbas's"
"Aberdeen's"
...
"zucchinis"
"zwieback"
"zwieback's"
"zygote"
"zygote's"
"zygotes"
"Ångström"
"Ångström's"
"éclair"
"éclair's"
"éclairs"
"éclat"
"éclat's"
"élan"
"élan's"
"émigré"
"émigré's"
"émigrés"
"épée"
"épée's"
"épées"
"étude"
"étude's"
其他提示
您可以使用任何动态缓冲区。这是 streambuf
:
for (asio::streambuf buf; auto n = asio::read_until(socket, buf, ';');) {
std::cout << std::string_view(
asio::buffer_cast<char const*>(buf.data()), n)
<< std::endl;
buf.consume(n);
}
或者,混合,显示 dynamic_string_buffer
模拟与 streambuf
相同的概念:
std::string str;
for (auto buf = asio::dynamic_buffer(str);
auto n = asio::read_until(socket, buf, ';');) {
std::cout << std::string_view(
asio::buffer_cast<char const*>(buf.data()), n)
<< std::endl;
buf.consume(n);
}
或者:
std::vector<unsigned char> vec;
for (auto buf = asio::dynamic_buffer(vec);
auto n = asio::read_until(socket, buf, ';');) {
std::cout << std::string_view(
asio::buffer_cast<char const*>(buf.data()), n)
<< std::endl;
buf.consume(n);
}