c++ - 字符串流与直接字符串
问题描述
我正在尝试将 STOMP 帧发送到服务器。我首先尝试使用 std::string 直接创建消息,但服务器一直抱怨我做错了。但是,当我使用 stringstream 创建消息时,它可以工作。任何人都可以发现我的错误吗?代码如图所示。它抱怨它在消息末尾找不到终止符 \0 (parsingmissingnullinbody)。
bool CheckResponse(const std::string& response)
{
// We do not parse the whole message. We only check that it contains some
// expected items.
bool ok {true};
ok &= response.find("ERROR") != std::string::npos;
ok &= response.find("ValidationInvalidAuth") != std::string::npos;
std::cout << response << "\n";
return ok;
}
BOOST_AUTO_TEST_CASE(connect_to_network_events){
// Always start with an I/O context object.
boost::asio::io_context ioc {};
// Create also a tls context
boost::asio::ssl::context ctx{boost::asio::ssl::context::tlsv12_client};
// Connection targets
const std::string url {"ltnm.learncppthroughprojects.com"};
const std::string port {"443"};
const std::string endpoint {"/network-events"};
// The class under test
WebSocketClient client {url, endpoint, port, ioc, ctx};
// MY ATTEMPT AT CREATING MESSAGE DIRECTLY, THIS FAILED
// const std::string message {"STOMP\naccept-version:1.2\nhost:transportforlondon.com\nlogin:fake_username\npasscode:fake_password\n\n\0"};
// THE FOLLOWING SUCCEEDED INSTEAD
const std::string username {"fake_username"};
const std::string password {"fake_password"};
std::stringstream ss {};
ss << "STOMP" << std::endl
<< "accept-version:1.2" << std::endl
<< "host:transportforlondon.com" << std::endl
<< "login:" << username << std::endl
<< "passcode:" << password << std::endl
<< std::endl // Headers need to be followed by a blank line.
<< '\0'; // The body (even if absent) must be followed by a NULL octet.
const std::string message {ss.str()};
std::string response;
// We use these flags to check that the connection, send, receive functions
// work as expected.
bool connected {false};
bool messageSent {false};
bool messageReceived {false};
bool messageMatches {false};
bool disconnected {false};
// Our own callbacks
auto onSend {[&messageSent](auto ec) {
messageSent = !ec;
}};
auto onConnect {[&client, &connected, &onSend, &message](auto ec) {
connected = !ec;
if (!ec) {
client.Send(message, onSend);
}
}};
auto onClose {[&disconnected](auto ec) {
disconnected = !ec;
}};
auto onReceive {[&client,
&onClose,
&messageReceived,
&messageMatches,
&message,
&response](auto ec, auto received) {
messageReceived = !ec;
response = received;
client.Close(onClose);
}};
// We must call io_context::run for asynchronous callbacks to run.
client.Connect(onConnect, onReceive);
ioc.run();
BOOST_CHECK(CheckResponse(response));
}
解决方案
创建std::string
fromconst char *
将忽略终止 NULL 字符。您可以使用char[]
构造函数,但我认为它不适合您的用例。
例子:
// Example program
#include <iostream>
#include <string>
int main()
{
std::string message1 {"STOMP\naccept-version:1.2\nhost:transportforlondon.com\nlogin:fake_username\npasscode:fake_password\n\n\0"};
std::cout << message1.length() << std::endl;
std::string message2 {"STOMP\naccept-version:1.2\nhost:transportforlondon.com\nlogin:fake_username\npasscode:fake_password\n\n"};
std::cout << message2.length() << std::endl;
message2.push_back('\0');
std::cout << message2.length() << std::endl;
}
输出:
97
97
98
因此,您只需要创建没有终止 NULL 字符的消息,然后附加\0
.
更新:如果你在C++14
你可能想要使用字符串文字:
using namespace std::string_literals;
// ...
std::string message = "STOMP\naccept-version:1.2\nhost:transportforlondon.com\nlogin:fake_username\npasscode:fake_password\n\n\0"s;
注意s
字符串末尾的 。
推荐阅读
- sql-server - 创建视图或物化视图以不断刷新
- vba - For 中的 VBA If 语句(即使满足 If 条件也会运行)
- snowflake-cloud-data-platform - 获取错误管道通知绑定失败“存储桶已从另一个雪花帐户绑定”
- html - 如何修改 AJAX 请求,以便在页面加载时隐藏空的依赖下拉菜单?
- r - R replace() 与逻辑测试冲突
- python - Matplotlib 底图动画需要更长的时间来处理更多帧
- r - 在图表上绘制多条线: geom_path:每组仅包含一个观察值。需要调整群体审美吗?
- amp-html - AMP-EMAIL:迭代来自 amp-state 的项目列表
- xcode11 - 创建 macOS 应用程序后关闭 Xcode 的解决方法?
- android-studio - 适用于所有 Google Play 用户的“此应用与您的所有设备都不兼容”