ipqhjjybj 2024-08-08 16:05 采纳率: 0%
浏览 24
已结题

c++ websocketpp连接币安 有报错,有偿求解

我想问 c++的 websocketpp库 连接币安的现货行情, 但是老报错, 求问是什么原因, ok的连接上了

这是连接的python代码


import websocket
import time
import threading
import json

def on_open(wsapp):
    print("on_open")

    input_msg = {
        "method": "SUBSCRIBE",
        "params": [
            "btcusdt@depth"
        ],
        "id": 1
    }
    print(input_msg)

    input_msg = json.dumps(input_msg)
    wsapp.send(input_msg)
    # print("send:", input_msg)
    
    # input()
    # def send_message():
    #     for i in range(10):
    #         wsapp.send(f"Hello {i}")
    #         time.sleep(1)
    #     wsapp.close()
    
    # threading.Thread(target=send_message).start()


def on_message(wsapp, message):
    print("on_message:", message)


def on_close(wsapp):
    print("on_close")


url = "wss://stream.binance.com:9443/stream?streams=BTCUSDT@ticker"
url = "wss://stream.binance.com:9443/stream"
#url = "wss://stream.binance.com:443/stream"
#url = "wss://data-stream.binance.vision"
wsapp = websocket.WebSocketApp(url,
                               on_open=on_open,
                               on_message=on_message,
                               on_close=on_close)
wsapp.run_forever()

我报错的c++代码

// #include <iostream>
// #include <thread>
// #include <vector>
// void thread_func() noexcept {
//     std::cout << "thread_func start ..." << std::endl;
//     std::vector<int> vec;
//     vec.push_back(1);
//     vec.push_back(2);
//     std::cout << vec.at(1) << std::endl;
// }
// int main (void) {
//     std::thread th1(thread_func);
//     th1.join();
//     return 0;
// }


#include <websocketpp/config/asio_client.hpp> 
#include <websocketpp/client.hpp> 
#include <iostream>

typedef websocketpp::client<websocketpp::config::asio_tls_client> client;
typedef websocketpp::lib::shared_ptr<websocketpp::lib::asio::ssl::context> context_ptr;

using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;

void on_open(websocketpp::connection_hdl hdl, client* c) {
    std::cout << "WebSocket connection opened!" << std::endl;

    websocketpp::lib::error_code ec;
    
    client::connection_ptr con = c->get_con_from_hdl(hdl, ec);
    if (ec) {
        std::cout << "Failed to get connection pointer: " << ec.message() << std::endl;
        return;
    }
    //std::string payload = "{\"userKey\":\"API_KEY\", \"symbol\":\"EURUSD,GBPUSD\"}";
    //std::string payload = "{\"method\":\"SUBSCRIBE\", \"params\":[\"btcusdt@depth\"], \"id\":1}";
    
    //binance
    std::string payload="{ \"method\": \"SUBSCRIBE\", \"params\": [ \"btcusdt@depth\"], \"id\": 1}";
    //okex
    //std::string payload = "{\"op\": \"subscribe\", \"args\": [{ \"channel\": \"books5\", \"instId\": \"BTC-USDT\"}]}";
    c->send(con, payload, websocketpp::frame::opcode::text);
}

void on_message(websocketpp::connection_hdl, client::message_ptr msg) {
    std::cout << "Received message: " << msg->get_payload() << std::endl;

}
void on_fail(websocketpp::connection_hdl hdl) {
    std::cout << "WebSocket connection failed!" << std::endl;
}
void on_close(websocketpp::connection_hdl hdl) {
    std::cout << "WebSocket connection closed!" << std::endl;
}

context_ptr on_tls_init(const char * hostname, websocketpp::connection_hdl) {
     context_ptr ctx = websocketpp::lib::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::sslv23);

     try {
              ctx->set_options(boost::asio::ssl::context::default_workarounds |
                               boost::asio::ssl::context::no_sslv2 |
                               boost::asio::ssl::context::no_sslv3 |
                               boost::asio::ssl::context::single_dh_use |
                               boost::asio::ssl::context::tlsv12_client );
              ctx->set_verify_mode(boost::asio::ssl::verify_none);
          } catch (std::exception& e) {
              std::cout << "TLS Initialization Error: " << e.what() << std::endl;
          }
     return ctx;
}

int main(int argc, char* argv[]) {
    client c;

    //std::string uri = "wss://echo.websocket.org";
    //std::string hostname = "echo.websocket.org";

    // 币安的没跑通
    std::string uri = "wss://stream.binance.com:9443/stream";
    //std::string uri = "wss://stream.binance.com:443/stream";
    std::string hostname = "stream.binance.com";
    //std::string hostname = "128.242.240.91";
    // 下面跑通了
    // std::string uri = "wss://ws.okx.com:8443/ws/v5/public";
    // std::string hostname = "ws.okx.com";
    // -------

    // std::string uri = "ws://124.222.224.186:8800";
    // std::string hostname = "124.222.224.186";
    // std::string hostname = "marketdata.tradermade.com/feedadv";
    
    // std::string uri = "wss://" + hostname;

    try {
      // Configure WebSocket++ client
      c.set_access_channels(websocketpp::log::alevel::all);
      c.clear_access_channels(websocketpp::log::alevel::frame_payload);
      c.set_error_channels(websocketpp::log::elevel::all);
         
      c.init_asio();

      // Set message, TLS initialization, open, fail, and close handlers
      c.set_message_handler(&on_message);
            
      c.set_tls_init_handler(bind(&on_tls_init, hostname.c_str(), ::_1));
      c.set_open_handler(bind(&on_open, ::_1, &c));
      c.set_fail_handler(bind(&on_fail, ::_1));
                   
      c.set_close_handler(bind(&on_close, ::_1));
      // Enable detailed error logging
      c.set_error_channels(websocketpp::log::elevel::all);          
           
      websocketpp::lib::error_code ec;
      client::connection_ptr con = c.get_connection(uri, ec);
      if (ec) {
                 std::cout << "Could not create connection because: " << ec.message() << std::endl;
                 return 0;
              }
      // Create a connection to the specified url
      std::cout << "connect" << std::endl;
      std::cout << "con:" << con->get_uri() << std::endl;
      
      c.connect(con);
      std::cout << "get_remote_endpoint:" << con->get_remote_endpoint() << std::endl;
      std::cout << "run" << std::endl;
      c.run();

    }  catch (websocketpp::exception const & e) {
            std::cout << "WebSocket Exception: " << e.what() << std::endl;
    }

    return 0;
}
  • 写回答

16条回答 默认 最新

  • 专家-皆知 2024-08-08 16:30
    关注

    引自免费微信小程序:皆我百晓生

    从你提供的C++代码来看,整体结构是正确的,但有几个潜在的问题可能引起连接失败或报错。下面我将逐个分析并提供相应的解决方案。

    1. TLS版本问题

    币安要求使用较新的TLS版本(比如TLS 1.2或更高),确保你的on_tls_init函数正确设置了支持这些版本。你的代码看起来已经尝试设置TLS 1.2,但为了更加明确和保险,可以考虑只启用TLS 1.2和TLS 1.3,同时确保没有其他配置干扰了这些设置。

    修改后的on_tls_init示例:

    context_ptr on_tls_init(const char * hostname, websocketpp::connection_hdl) {
        context_ptr ctx = websocketpp::lib::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::sslv23);
    
        try {
            ctx->set_options(
                boost::asio::ssl::context::default_workarounds |
                boost::asio::ssl::context::no_sslv2 |
                boost::asio::ssl::context::no_sslv3 |
                boost::asio::ssl::context::single_dh_use |
                boost::asio::ssl::context::no_tlsv1 |
                boost::asio::ssl::context::no_tlsv1_1 |
                boost::asio::ssl::context::tls12 |
                boost::asio::ssl::context::tls13
            );
            ctx->set_verify_mode(boost::asio::ssl::verify_none);
        } catch (std::exception& e) {
            std::cerr << "TLS Initialization Error: " << e.what() << std::endl;
        }
        return ctx;
    }
    

    2. Hostname验证问题

    在某些情况下,服务器可能会检查连接请求中的主机名是否与预期匹配。尽管你的代码设置了hostname,但确保WebSocket库能够正确使用它。虽然默认情况下WebSocket++应该能处理好这个,但有时显式设置SNI(Server Name Indication)可以帮助解决特定的连接问题。

    3. 错误处理和日志

    你的代码已经启用了详细的日志记录,这很好,但确保你仔细查看输出的日志,特别是当连接失败时的日志信息,这通常会提供错误的具体原因。例如,SSL握手失败、证书验证问题等都会在这里体现。

    4. 确保网络环境允许

    有时候,特别是在公司或学校网络环境下,存在防火墙或代理设置可能阻止或干扰WebSocket连接。确认你的网络环境允许连接到币安的WebSocket服务。

    5. 最终检查

    • 确保你正在使用的WebSocket++库是最新的,因为它可能包含对新协议或安全更新的支持。
    • 重新检查你的API密钥或订阅方法是否符合币安的要求。虽然你的示例代码中没有使用API密钥,但如果币安的WebSocket服务需要认证,确保你正确添加了认证逻辑。
    • 尝试连接其他WebSocket服务,以确定问题是出在你的代码还是特定于币安的服务。

    如果你已经检查过上述所有方面,并且问题仍然存在,建议捕获并打印出更详细的错误信息,这通常能提供更精确的故障定位点。

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 8月11日
  • 修改了问题 8月9日
  • 创建了问题 8月8日

悬赏问题

  • ¥15 求!!为啥出错,咋改正
  • ¥50 关于在matlab上对曲柄摇杆机构上一点的运动学仿真
  • ¥15 jetson nano
  • ¥15 :app:debugCompileClasspath'.
  • ¥15 windows c++内嵌qt出现数据转换问题。
  • ¥20 公众号如何实现点击超链接后自动发送文字
  • ¥15 用php隐藏类名和增加类名
  • ¥15 算法设计与分析课程的提问
  • ¥15 用MATLAB汇总拟合图
  • ¥15 智能除草机器人方案设计