// std:string _sql_statement;
// char _client_data[max_data_length];
// size_t bytes_transferred;
void tcp_proxy::Bridge::handle_read_fclient(const error_code& error, const size_t & bytes_transferred)
{
if (!error) {
asio::async_write(*_upstream_socket.get(),
asio::buffer(_client_data, bytes_transferred),
boost::bind(&Bridge::handle_write_tserver,
shared_from_this(),
asio::placeholders::error)
);
_sql_statement.append(_client_data, bytes_transferred);
std::cout << _sql_statement << "\n";
}
else {
stop();
}
}
当我运行 mysql-client 并发送 sql 查询时,我得到以下输出:
����=9漢 �\�gOx� �u%e��A ��
��jxt�6���� �bc ���z�
�-x��w<�0NH�+�,�/�#�'�0�$�(��g@�kj��� ��
23895�A��<=/��
*(
+-3GEA1�����Ȩf� ��b�_�Epx����D�47�~�;%/x��C)�Q���D3 ���n�]�B�brU�N�ݘ%_\�
7F�e����
u��ED�Ϳ�T�Q����XyȀt�xb8��� ����������'�Zm�V엇DT��!»
����@��2�� Nd۠;��̭�1�t5QtU�M�`�B�<�վmwX[�
�0�5���]��yM!��}/E��|g$�&���8�&~�a?C��_���z��տ�ɝN�D�LJ0�z����|�v,�r�$]���*HJ�$'��xGQ)P�4��TI�=8qc?���)`��N?_U率`���K��U4��8f��� &�
我尝试使用 printf,但没有成功。我会很高兴收到任何提示、文献链接。
它正在工作。 Mysql 协议不是基于文本的。将其作为文本打印是不合适的。相反,请考虑十六进制转储,例如:
_sql_statement.assign(_client_data, bytes_transferred);
std::cout << "Received " << bytes_transferred << " bytes: ";
{
std::ostream hex(std::cout.rdbuf());
hex << std::hex << std::showbase << std::setfill('0');
for (auto i = 0; i < bytes_transferred; ++i) {
uint8_t octet = _client_data[i];
hex << " " << std::setw(4) << static_cast<int>(octet);
}
}
std::cout << std::endl;
注意我还将
更改为append
以避免无限增长。另请考虑将assign
重命名为_sql_statemtent
以避免误导性名称。_data
一些事情:
如果只有一个点锁定互斥体,那么互斥体就没用了
为了避免出现问题,请不要在潜在的异步操作期间
close()
。相反 cancel()
它们并让错误处理通过 shared_from_this()
进行清理
对于接受者来说也是如此,仅设置
_stopped = true
不会强制待处理的接受完成。相反,cancel() _acceptor
。
请勿无缘无故滥用
shared_ptr::get()
、atomic<T>::load()
和atomic<T>::store()
避免异步读取周围的代码重复:
void tcp_proxy::Bridge::handle_connection(error_code const& error) {
if (!error) {
do_read_fserver();
do_read_fclient();
} else {
std::cerr << "Connect Error! Error code = " << error.value() << ". Message : " << error.message() << "\n";
stop();
}
}
并在写入完成中重新使用相同的
do_read_fXXX()
函数。
正确处理EOF。遇到EOF时有可能已经接收到数据。因此,将数据写入另一端破坏连接:
if (!error || error == asio::error::eof) {
我将把它作为练习留给读者,以选择跟踪关闭状态(参见例如boost::asio干净地断开连接)
您在...
proxy.stop_proxy()
完成后致电ios.run()
。从定义上来说这是无用的。考虑忽略它,或者将其放在更有用的位置(例如,在 signal_set::async_wait
处理程序中?)
我还在 Gitlab 上创建了一个包含这些评论的分支:https://gitlab.com/v-danis/tcp-proxy/-/merge_requests/1(分支https://gitlab.com/bitbucket54/tcp) -proxy/-/tree/sehe-review?ref_type=heads).