Tcp代理mysql。从mysql客户端接收到的数据以奇怪的符号输出

问题描述 投票:0回答:1
// 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,但没有成功。我会很高兴收到任何提示、文献链接。

c++ mysql string proxy boost-asio
1个回答
0
投票

它正在工作。 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).

本地演示:

© www.soinside.com 2019 - 2024. All rights reserved.