Hi, I’m trying to create a websocket client in c++ to fetch data from binance futures public streams. While I’m sending a request to upgrade the connection to websocket I’m getting a 400 BAD request response.
Some snippets from my code:
client_fd = socket(AF_INET, SOCK_STREAM, 0)
const string binanceBaseUrl = “wss://fstream.binance.com”;
string handshake = “GET /ws/bnbusdt@depth HTTP/1.1\r\n”
"Host: " + binanceBaseUrl + “\r\n”
“Upgrade: websocket\r\n”
“Connection: Upgrade\r\n”
“Sec-WebSocket-Key: key\r\n”
“Sec-WebSocket-Version: 13\r\n\r\n”;
send(client_fd, handshake.c_str(), handshake.length(), 0)
valread = recv(client_fd, buffer, sizeof(buffer),0);
printf(“%s\n”, buffer);
OUTPUT :
HTTP/1.1 400 Bad Request
Server: awselb/2.0
Date: Fri, 22 Dec 2023 06:46:45 GMT
Content-Type: text/html
Content-Length: 122
Connection: close
400 Bad Request
400 Bad Request
The base URL should contain the /ws part, so wss://fstream.binance.com/ws
.
This is possibly the reason, but I can’t test your code since I don’t know how you’re declaring some variables.
Hi, this is my code:
#include
#include
#include
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include
#include
#include
const char* server_address = “fstream.binance.com ”;
const int server_port = 443;
std::string generateWebSocketKey() {
std::random_device rd;
std::mt19937_64 generator(rd());
std::uniform_int_distribution distribution(0, 255);
// Generate a random 16-byte value
std::string randomBytes;
randomBytes.reserve(16);
for (int i = 0; i < 16; ++i) {
randomBytes.push_back(static_cast<char>(distribution(generator)));
}
// Base64 encode the random value
std::ostringstream base64Key;
base64Key.fill('0');
base64Key << std::hex << std::setw(2) << std::setfill('0');
for (unsigned char byte : randomBytes) {
base64Key << '%' << std::setw(2) << static_cast<unsigned>(byte);
}
return base64Key.str();
}
int main() {
int client_socket = socket(AF_INET, SOCK_STREAM, 0);
if (client_socket == -1) {
std::cerr << “Error creating socket” << std::endl;
return 1;
}
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(server_port);
if (inet_pton(AF_INET, "52.197.149.233", &server_addr.sin_addr) <= 0) {
std::cerr << "Error converting address" << std::endl;
close(client_socket);
return 1;
}
if (connect(client_socket, reinterpret_cast<struct sockaddr*>(&server_addr), sizeof(server_addr)) == -1) {
std::cerr << "Error connecting to the server" << std::endl;
close(client_socket);
return 1;
}
std::string key = generateWebSocketKey();
std::cout<<key<<" = key\n";
std::string request =
"GET /ws HTTP/1.1\r\n"
"Host: fstream.binance.com\r\n"
"Upgrade: websocket\r\n"
"Connection: Upgrade\r\n"
"Sec-WebSocket-Key: "+ key + "\r\n"
"Sec-WebSocket-Version: 13\r\n\r\n";
send(client_socket, request.c_str(), request.size(), 0);
char response[4096];
ssize_t bytes_received = recv(client_socket, response, sizeof(response), 0);
if (bytes_received == -1) {
std::cerr << "Error receiving data" << std::endl;
} else {
std::cout << "Server response:\n" << std::string(response, bytes_received) << std::endl;
}
// Close the socket
close(client_socket);
return 0;
}
I obtained the IP by “ping fstream.binance.com ”
Once the handshake is established, I will send a subscription request to a stream.
I’m stuck at the handshake phase.
Khun
December 24, 2023, 4:49pm
3
URL should be wss://fstream.binance.com/ws …
Also you want to get listenkey if you are creating a stream for an account
Hi, I have pasted the code above can you please have a look.