我正在使用Winsock中的TCP套接字在C中编写Minecraft Classic Server,我正在编写执行'heartbeat'的函数,只是一个HTTP请求,它应该向我返回一个URL - 根本没有标题或HTML
它将数据发送到Minecraft.net(至少它说它确实如此),但它只是在那里坐了几分钟后最终告诉我它没有来自minecraft.net的数据,即它显示为“HeartBeat:收到了来自minecraft.net的数据“
到目前为止,我有以下代码(不包括WSAStartup等):
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;
}
}
有人可以指出我出错的地方吗?万分感谢。
答案 0 :(得分:1)
您没有发送HTTP请求。
(最小)HTTP请求必须至少是字符串:
char request[256] ="GET / HTTP/1.0\r\n\r\n";
或者在HTTP 0.9的情况下:
char request[256] ="GET /\r\n\r\n";
您必须只发送该字符串,而不是包含大量0字节的整个请求缓冲区,所以请执行:
send(clSock, request, strlen(request), 0)
您只进行了1次recv()调用,可能无法读取整个响应。你应该读取直到连接关闭(直到recv()返回0)。或者要真正遵循HTTP协议,您需要解析响应,查找Content-Length标头。读取所有标题,然后读取正文中的字节数(如果有)。要真正处理HTTP的所有细节,您确实需要一个HTTP库。