HTTP GET request using C++ WinSock, Binance API - c++

I'm trying first to connect with Binance api endpoint which is /api/v3/ping.
However I'm getting "HTTP/1.1 400 Bad Request" response, what should be updated in this code?
int main()
{
WSADATA wsa;
SOCKET s;
struct sockaddr_in server;
char buffer[BUFFERSIZE];
std::string request;
std::cout<<("Initialising Winsock...\n");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
std::cout<<("Failed. Error Code : %d", WSAGetLastError());
return 1;
}
std::cout<<("Initialised.\n");
if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
{
std::cout << ("Could not create socket : %d", WSAGetLastError());
}
std::cout << ("Socket created.\n");
const wchar_t* IP = _T("52.84.198.235");
InetPton(AF_INET, IP, &server.sin_addr.s_addr);
server.sin_family = AF_INET;
server.sin_port = htons(443);
if (connect(s, (struct sockaddr*)&server, sizeof(server)) < 0)
{
std::cout<<("connect error\n");
return 1;
}
std::cout<<("Connected\n");
request += "GET /api/v3/ping HTTP/1.1\r\nHost: api.binance.com\r\n\r\n";
if (send(s, request.c_str(), strlen(request.c_str()), 0) < 0)
{
std::cout<<("Send failed\n");
return 1;
}
std::cout << ("Data Send\n");
std::string response;
int resp_leng;
response = "";
resp_leng = BUFFERSIZE;
while (resp_leng)
{
resp_leng = recv(s, (char*)&buffer, BUFFERSIZE, 0);
if (resp_leng > 0)
response += std::string(buffer).substr(0, resp_leng);
}
std::cout << response << "\n";
closesocket(s);
WSACleanup();
return 0;
}
I was using info from a few sites and stackoverflow questions, I'm wondering if it can be about SSL?

Related

400 bad request error when send a GET http request by using winsock library

I'm trying to send a GET request to a webserver(example: www.coursera.org,...). But sServer returns a response header: HTTP/1.1 400 bad request
I used Winsock in C++ and establish a socket connect to server. Then, send a GET request to server.
int main(void) {
get_Website("www.coursera.org");
cout << website_HTML;
cout << "\n\nPress ANY key to close.\n\n";
cin.ignore(); cin.get();
return 0;
}
void get_Website(string url)
{
WSADATA wsaData;
SOCKET Socket;
SOCKADDR_IN SockAddr;
int lineCount = 0;
int rowCount = 0;
struct hostent* localHost;
string srequete;
char* localIP;
srequete = "GET / HTTP/1.0\r\n";
srequete += "Host: www.coursera.org\r\n";
srequete += "Connection: close\r\n\r\n";
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
cout << "WSAStartup failed.\n";
system("pause");
//return 1;
}
Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
localHost = gethostbyname(url.c_str());
localIP = inet_ntoa(*(struct in_addr *)*localHost->h_addr_list);
SockAddr.sin_port = htons(443);
SockAddr.sin_family = AF_INET;
SockAddr.sin_addr.s_addr = inet_addr(localIP);
if (connect(Socket, (SOCKADDR*)(&SockAddr), sizeof(SockAddr)) != 0) {
cout << "Could not connect";
system("pause");
//return 1;
}
send(Socket, srequete.c_str(), strlen(srequete.c_str()), 0);
int nDataLength;
while ((nDataLength = recv(Socket, buffer, 10000, 0)) > 0) {
int i = 0;
while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r') {
website_HTML += buffer[i];
i += 1;
}
}
closesocket(Socket);
WSACleanup();
}
The problem seems to be GET request that is wrong?
They can't parse your request because you are trying to send it to https port (443) unencrypted. You can try to send it http port (80), but they will redirect you to https://coursera.org anyway.

error in send data to server

Why when run the program and send data to server return this errorrecv failed: Transport endpoint is not connected or don't show server accepted just show the message of send data function in client
server.cpp:
int main() {
char packet[30];
char buffer[20] = "I got your message";
int conn_sock, comm_sock, n, m;
struct sockaddr_in server_addr, client_addr;
if ((conn_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("Couldn't create socket");
exit(1);
}
cout << "Already create socket!!!\n" << endl;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(0);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
memset(&server_addr, 0, sizeof(server_addr));
if (bind(conn_sock, (struct sockaddr *) &server_addr, sizeof(server_addr))
== -1) {
perror("couldn't bind");
exit(1);
}
if (listen(conn_sock, 10) == -1) {
perror("couldn't listen");
exit(1);
}
cout << "Listening For Connection...\r" << endl;
socklen_t len = sizeof(server_addr);
if (getsockname(conn_sock, (struct sockaddr *) &server_addr, &len) == -1)
perror("getsockname");
else
printf("port number %d\n", ntohs(server_addr.sin_port));
while (1) {
memset(&client_addr, 0, sizeof(client_addr));
if ((comm_sock = accept(conn_sock, (struct sockaddr *) &client_addr,
(socklen_t *) &client_addr)) == -1) {
perror("couldn't accept\n");
continue;
}
cout << "accepted" << endl;
bzero(packet, 10);
m = recv(conn_sock, packet, 10, 0);
if (m < 0) {
perror("recv failed");
exit(1);
}
cout<<"recieved"<<endl;
/* Write a response to the client */
n = send(conn_sock, buffer, sizeof(buffer), 0);
if (n < 0) {
perror("ERROR send to client");
exit(1);
}
close(n);
close(m);
close(comm_sock);
}
close(conn_sock);
return 0;
}
cilent.cpp:
#define MYPORT 51833
namespace personalization {
bool client::conn() {
//create socket if it is not already created
if (sock == -1) {
//Create socket
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
perror("Could not create socket");
}
cout << "Socket created" << endl;
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(MYPORT);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(sock , (struct sockaddr *)&server_addr , sizeof(server_addr)) < 0)
{
perror("connect failed. Error");
return false;
}
cout<<"Connected\n";
return true;
close(sock);
}
bool client::send_data() {
//Send some data
if( send(sock , packet , sizeof( packet ) , 0) < 0)
{
perror("Send failed");
return false;
}
cout<<"Data send\n";
return true;
close(sock);
}
bool client::rec_data() {
char buffer[20];
string reply;
//Receive a echo from the server
if (recv(sock, buffer, sizeof(buffer), 0) < 0) {
perror("receive failed");
return false;
}
reply = buffer;
return true;
close(sock);
}
client::client() {
// TODO Auto-generated constructor stub
sock=-1;
}
output is:
server:Already create socket!!!
Listening For Connection...
port number 51833
client: Socket created
Connected
Data send
receive failed: Connection reset by peer
or:
server:Already create socket!!!
Listening For Connection...
port number 51833
client:Socket created
Connected
Data send
srver:accepted
recv failed: Transport endpoint is not connected
In the server's recv and send calls, you need to pass the socket returned from accept.
So instead of
m = recv(conn_sock, packet, 10, 0);
do
m = recv(comm_sock, packet, 10, 0);
Same goes for the send call.
Also, don't call close on n and m, that is to say remove these two lines of code:
close(n);
close(m);
EDIT: Sorry, while I'm at it, this is probably not what you intended in the client's send_data and rec_data:
return true;
close(sock);

C++ cant receive UDP-Packets (Socket)

I am working on a C++ UDP program, that sends a string to another client and should receive an answer.
Sending works fine, but i cant receive any packets. I looked with wireshark and my computer receives the packet at the right port and from the right IP, but my program seems to ignore them.
Do you have any idea?
int startWinsock(void);
int main()
{
long receive;
SOCKET sock;
char buffer[256];
SOCKADDR_IN si_me;
SOCKADDR_IN si_other;
///////////// Start Winsock ///////////////
receive = startWinsock();
if (receive != 0)
{
printf("Error: startWinsock, error code: %d\n", receive);
return 1;
}
else
{
printf("Winsock started!\n");
}
//////////// Create UDP Socket //////////////
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == INVALID_SOCKET)
{
printf("Fehler: Socket could not be created, errorcode: %d\n", WSAGetLastError());
return 1;
}
else
{
printf("UDP Socket created!\n");
}
si_me.sin_family = AF_INET;
si_me.sin_port = htons(1198);
si_me.sin_addr.s_addr = htonl(INADDR_ANY);
si_other.sin_family = AF_INET;
si_other.sin_port = htons(2000);
si_other.sin_addr.s_addr = inet_addr("10.2.134.10");
receive = connect(sock, (SOCKADDR*)&si_other, sizeof(SOCKADDR));
if (receive == SOCKET_ERROR)
{
cout << "Error : Connection Failed, Errorcode: " << WSAGetLastError() << endl;
}
else
{
cout << "Connected to" << si_other.sin_addr.s_addr << endl;
}
static int timeout = 500;
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
// char broadcast = 1;
// setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast));
while (1)
{
printf("Insert Text: ");
gets(buffer);
//rc = sendto(s, buf, strlen(buf), 0, (SOCKADDR*)&addr, sizeof(SOCKADDR_IN));
receive = send(sock, buffer, strlen(buffer), 0);
if (receive == SOCKET_ERROR)
{
//printf("error: sendto, error code: %d\n",WSAGetLastError());
printf("Error: send, error code: %d\n", WSAGetLastError());
//return 1;
}
else
{
printf("%d bytes sent!\n", receive);
}
static int timeout = 500;
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
int wait = 0;
while (wait == 0)
{
//rc = recvfrom(s, buf, 256, 0, (SOCKADDR*)&addr, sizeof(SOCKADDR_IN));
receive = recv(sock, buffer, sizeof(buffer), 0);
if (receive == SOCKET_ERROR)
{
//printf("Fehler: recvfrom, fehler code: %d\n",WSAGetLastError());
printf("Fehler: recv, fehler code: %d\n", WSAGetLastError());
//return 1;
}
else
{
wait = 1;
printf("%d bytes received!\n", receive);
buffer[receive] = '\0';
printf("Received: %s\n", buffer);
}
}
}
getchar();
return 0;
}
int startWinsock(void)
{
WSADATA wsa;
return WSAStartup(MAKEWORD(2, 0), &wsa);
}
To make it so your code works nearly as-is by sending to itself, do the following:
change the "me" port to match "other"... si_me.sin_port = htons( 2000 );
bind to it... bind( sock, (SOCKADDR*)&si_me, sizeof( SOCKADDR ) ); just before connect
As UDP is Datagram-Oriented and connectionless, you need to use recvfrom/sento instead of recv/send. Also the receivetimeout should be set with at timeval.
struct timeval tv;
tv.tv_sec = 5;
tv.tv_usec = 0;
setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));

Improve server to deal with multiple clients

I'm trying to create a server that talks with 2 clients, 1 in each time. After the talking with one client, the server sends a message to both clients.
I found a basic code of a server, and I tried to upgrade it to accept multiple number of connections, and I saw 2 ways of it : threads, or doing array of sockets, but I couldn't understand it.
Can someone explain me how to use threads and give examples please?
This is the code :
int main()
{
WSADATA WsaDat;
if (WSAStartup(MAKEWORD(2, 2), &WsaDat) != 0)
{
std::cout << "WSA Initialization failed!\r\n";
WSACleanup();
system("PAUSE");
return 0;
}
SOCKET Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (Socket == INVALID_SOCKET)
{
std::cout << "Socket creation failed.\r\n";
WSACleanup();
system("PAUSE");
return 0;
}
SOCKADDR_IN serverInf;
serverInf.sin_family = AF_INET;
serverInf.sin_addr.s_addr = INADDR_ANY;
serverInf.sin_port = htons(8888);
if (bind(Socket, (SOCKADDR*)(&serverInf), sizeof(serverInf)) == SOCKET_ERROR)
{
std::cout << "Unable to bind socket!\r\n";
WSACleanup();
system("PAUSE");
return 0;
}
listen(Socket, 1);
SOCKET TempSock = SOCKET_ERROR;
while (TempSock == SOCKET_ERROR)
{
std::cout << "Waiting for incoming connections...\r\n";
TempSock = accept(Socket, NULL, NULL);
}
// If iMode!=0, non-blocking mode is enabled.
u_long iMode = 1;
ioctlsocket(Socket, FIONBIO, &iMode);
Socket = TempSock;
std::cout << "Client connected!\r\n\r\n";
// Main loop
for (;;)
{
char *szMessage = "Welcome to the server!\r\n";
send(Socket, szMessage, strlen(szMessage), 0);
int nError = WSAGetLastError();
if (nError != WSAEWOULDBLOCK&&nError != 0)
{
std::cout << "Winsock error code: " << nError << "\r\n";
std::cout << "Client disconnected!\r\n";
// Shutdown our socket
shutdown(Socket, SD_SEND);
// Close our socket entirely
closesocket(Socket);
break;
}
Sleep(1000);
}
WSACleanup();
system("PAUSE");
return 0;
}
To do so you need one server socket and a clientsocket array like this:
SERVER:
ACCEPT:
int clientsock[2];
minsocks = 0;
numsocks = 2;
while(minsock < numsocks)
{
clientsock[minsock] = accept(serversock,
(struct sockaddr *) &clientaddr,
(socklen_t *)&clientaddrlen);
minsock++;
}
RECIEVE:
char message[6];
int data;
int limit = 6;
for(int i = 0; i < NUMSOCK; i++)
{
int in = recv(clientsock[i], &message[index], limit, 0);
if(in > 0)
{
index += in;
limit -= in;
}
else if ( in == 0 )
printf("Connection closed\n");
else
printf("recv failed: %d\n", WSAGetLastError());
}
This should be a good beginning for you to start with.
Threads - C version
pthread_t sniffer_thread;
if( pthread_create( &sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0)
{
perror("could not create thread");
return 1;
}
//Now join the thread , so that we dont terminate before the thread
//pthread_join( sniffer_thread , NULL);
puts("Handler assigned");
}
/*
* This will handle connection for each client
* */
void *connection_handler(void *socket_desc)
{
//Get the socket descriptor
int sock = *(int*)socket_desc;
int read_size;
char *message , client_message[2000];
while(in != 0)
{
int in = recv(socket_desc, &client_message[index], limit, 0);
if(in > 0)
{
index += in;
limit -= in;
}
else
printf("recv failed: %d\n", WSAGetLastError());
}
//Free the socket pointer
free(socket_desc);
return 0;
}

Error connecting to server by proxy server in c++ socket programming

The code for connection :
cout << "connecting1\n";
WSADATA wsadata;
int iResult = WSAStartup (MAKEWORD(2,2), &wsadata );
if (iResult !=NO_ERROR )
printf("\nmyERROR at WSAStartup()\n");
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
perror("error opening socket"); return -1;
}
struct sockaddr_in sin;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = inet_addr(host.c_str());
sin.sin_family = AF_INET;
if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
perror("error connecting to host"); return -1;
}
const int query_len = query.length() + 1; // trailing '\0'
if (send(sock, query.c_str(), query_len, 0) != query_len) {
perror("error sending query"); return -1;
}
const int buf_size = 1024 * 1024;
while (true) {
std::vector<char> buf(buf_size, '\0');
const int recv_len = recv(sock, &buf[0], buf_size - 1, 0);
if (recv_len == -1) {
perror("error receiving response"); return -1;
} else if (recv_len == 0) {
std::cout << std::endl; break;
} else {
std::cout << &buf[0];
fprintf(fp, "%s", &buf[0]);
}
}
In wifi without proxy it works fine, but when we use proxy server, net can be accessed in chrome, but the above code prints
connecting1
error connecting to host
What is the problem ?