I’m writing a Minecraft Classic Server in C using TCP sockets in Winsock and I’m writing the function to perform a ‘heartbeat’, just an HTTP request which should return a URL to me – no headers or HTML at all.
It sends the data to Minecraft.net (at least it says it does) but it just sits there for a few minutes after that and eventually tells me that it got no data from minecraft.net, ie it reads “HeartBeat: Recieved no data from minecraft.net”
I have the following code so far (excluding WSAStartup etc.):
void HeartBeat()
{
unsigned int clSock;
struct hostent *host;
struct sockaddr_in server_addr;
char buffer[128] = "";
char request[256] = "GET /"; //(I will not show the rest of the request...)
if((clSock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("HeartBeat: Error creating socket\n");
return;
} else {
printf("HeartBeat: Success in creating socket\n");
}
printf("HeartBeat: Resolving hostname 'www.minecraft.net'... ");
if((host = gethostbyname("www.minecraft.net")) == NULL)
{
printf("failed\n");
return;
} else {
printf("success!\n");
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(80);
server_addr.sin_addr.s_addr = *((unsigned long*)host->h_addr);
if (connect(clSock, (SOCKADDR*) &server_addr, sizeof(server_addr)) == SOCKET_ERROR)
{
printf("HeartBeat: Error conneting to www.minecraft.net\n");
return;
} else {
printf("HeartBeat: Connected to www.minecraft.net\n");
}
if (send(clSock, request, sizeof(request), 0) < 0)
{
printf("HeartBeat: Sending data failed.\n");
closesocket(clSock);
return;
} else {
printf("HeartBeat: Success in sending data.\n");
}
if ((recv(clSock, buffer, sizeof(buffer), 0)) == 0)
{
printf("HeartBeat: Received no data from www.minecraft.net\n");
closesocket(clSock);
return;
} else {
printf("HeartBeat: Yay, success! Url is '%s'", buffer);
closesocket(clSock);
return;
}
}
Could someone please point out where I’ve gone wrong? Thanks a million.
You’re not sending an HTTP request.
A (minimal) HTTP request would have to be at least the string:
Or in the case of HTTP 0.9:
You must send just that string, not the whole request buffer containing a lot of 0 bytes, so do:
You are doing just 1 recv() call, that might not read the entire response. You’re supposed to read until the connection closes (until recv() returns 0). Or to really follow the HTTP protocol, you need to parse the response, look for a Content-Length header. Read all the headers, then read the number of bytes in the body (if any). To really cope with all the minute details of HTTP, you really need a HTTP library though.