提升 ASIO SSL 写入部分数据
boost asio ssl writing part of data
我的客户端-服务器应用程序,通过boost asio进行通信,usign功能:
当连接开始时,客户端向服务器发送一堆请求,服务器发回一些响应。 将asio::ssl添加到项目后,我遇到了以下问题。
有时,服务器只读取请求的第一个固定部分,这是 1/5 次。当客户端断开连接时,服务器将获取所有错过的请求。
在客户端,一切似乎都很好,调用的 callbakcs 没有错误,写入大小是正确的。但是数据包嗅探器的结果显示客户端不发送这部分请求。
客户:
每个"帧"的大小位于标题中,首先必须至少读取标题。 线程工作线程用于后台工作,并将准备好的数据包推送到存储。
using SSLSocket = boost::asio::ssl::stream<boost::asio::ip::tcp::socket>;
class AsyncStrategy :
public NetworkStrategy
{
// other data...
void _WriteHandler(const boost::system::error_code& err, size_t bytes);
bool Connect(const boost::asio::ip::tcp::endpoint& endpoint);
void _BindMessage();
void _BindMessageRemainder(size_t size);
void _AcceptMessage(const boost::system::error_code& err_code, size_t bytes);
void _AcceptMessageRemainder(const boost::system::error_code& err_code, size_t bytes);
// to keep io_service running
void _BindTimer();
void _DumpTimer(const boost::system::error_code& error);
void _SolveProblem(const boost::system::error_code& err_code);
void _Disconnect();
bool verify_certificate(bool preverified,
boost::asio::ssl::verify_context& ctx);
PacketQuery query;
boost::array <Byte, PacketMaxSize> WriteBuff;
boost::array <Byte, PacketMaxSize> ReadBuff;
boost::asio::ip::tcp::endpoint ep;
boost::asio::io_service service;
boost::asio::deadline_timer _Timer{ service };
boost::asio::ssl::context _SSLContext;
SSLSocket sock;
boost::thread Worker;
bool _ThreadWorking;
bool _Connected = false;
};
AsyncStrategy::AsyncStrategy( MessengerAPI& api)
: API{api},_SSLContext{service,boost::asio::ssl::context::sslv23 },
sock{ service,_SSLContext }, _Timer{service},
Worker{ [&]() {
_BindTimer();
service.run();
} },
_ThreadWorking{ true }
{
_SSLContext.set_verify_mode(boost::asio::ssl::verify_peer);
_SSLContext.set_verify_callback(
boost::bind(&AsyncStrategy::verify_certificate, this, _1, _2));
_SSLContext.load_verify_file("ca.pem");
}
bool AsyncStrategy::verify_certificate(bool preverified,
boost::asio::ssl::verify_context& ctx)
{
return preverified;
}
void AsyncStrategy::_BindMessage()
{
boost::asio::async_read(sock, buffer(ReadBuff,BaseHeader::HeaderSize()),
boost::bind(&AsyncStrategy::_AcceptMessage, this, _1, _2));
}
bool AsyncStrategy::Connect(const boost::asio::ip::tcp::endpoint& endpoint)
{
ep = endpoint;
boost::system::error_code err;
sock.lowest_layer().connect(ep, err);
if (err)
throw __ConnectionRefused{};
// need blocking handshake
sock.handshake(boost::asio::ssl::stream_base::client, err);
if (err)
throw __ConnectionRefused{};
_BindMessage();
return true;
}
void AsyncStrategy::_AcceptMessage(const boost::system::error_code& err_code, size_t bytes)
{
// checking header, to see, packet ends or not
// if there is more data in packet, read rest my binding function
// pseudocode
if( need_load_more )
_BindMessageRemainder(BytesToReceive(FrameSize));
return;
}
// if not use this bind this function next time
_CheckPacket(ReadBuff.c_array(), bytes);
_BindMessage();
}
void AsyncStrategy::_AcceptMessageRemainder(const boost::system::error_code& err_code, size_t bytes)
{
if (err_code)
{
_SolveProblem(err_code);
return;
}
_CheckPacket(ReadBuff.c_array(), bytes + BaseHeader::HeaderSize());
_BindMessage();
}
bool AsyncStrategy::Send(const TransferredData& Data)
{
// alreay known, that that data fits in buffer
Data.ToBuffer(WriteBuff.c_array());
boost::asio::async_write(sock,
buffer(WriteBuff, Data.NeededSize()),
boost::bind(&AsyncStrategy::_WriteHandler, this, _1, _2));
return true;
}
void AsyncStrategy::_WriteHandler(const boost::system::error_code& err, size_t bytes)
{
if (err)
_SolveProblem(err);
}
删除所有ssl内容后,数据传输是正常的。正如我所提到的,在SSL集成之前一切正常。
寻找解决方案,我发现如果延迟发送,尝试200毫秒,所有数据传输正常。
Win10, boost 1.60, OpenSSL 1.0.2n
我想我的代码中可能存在错误,但我几乎尝试了我认为的所有内容。寻求建议。
我们看不出Send
实际上是如何称呼的。
也许它需要同步。
我们可以让它每次都重用相同的缓冲区,因此重叠的两次写入将破坏该缓冲区。
我们还可以看到,您没有验证Data
参数的大小是否适合PacketMaxSize
缓冲区。
这意味着如果超过预期的缓冲区大小,您不仅会丢失数据,而且还会调用未定义的行为
相关文章:
- 如何在 c++ 中比较 2 个链表并将匹配的数据放入另一个链表中
- 将文件读入数据结构
- 我觉得我放入结构中的输入代码可以压缩,关于如何在保持代码简短的同时保持数据个性化的任何建议?
- 将数据文件读入结构 C++
- 如何将csv中的数据放入c++中的字符串向量中,而绝对没有任何作用
- 有没有办法"QByteArray"变量数据直接放入变量"int"而无需强制转换?
- 将文本文件数据读入字符数组时提取运算符的歧义
- 将 Python 数据读入C++代码中
- 如何将文件的特定部分读入私有数据成员
- 读取访问冲突. _Mycont 在 C++ 中将 udp 数据放入向量时出现 nullptr 错误
- 每次我将对象推入矢量时都会丢失数据
- 如何通过解析缓冲区并将数据放入正确的结构来处理传入的数据包连接?
- 使用 boost::p ython 将数据缓冲区放入C++中
- C 从TXT文件读取数据并将其放入2D数组中
- 将数据文件读入对象数组时出现问题
- C++ 读取.csv文件,将数据放入变量中,然后放入对象中
- Linux 在从文件中读取数据并放入矢量时比 Windows 快得多.txt.我将如何加速Windows以做同样的事情
- 从 csv 文件中获取不同类型的数据,并将其放入 C++ 中的 typedef 结构中
- 如何将 v4l2 中的数据放入 c++ 向量
- 将数据读入结构中的 void* 变量