使用 C 套接字创建服务器并出现错误
Creating server with C sockets and getting error
我正在学习使用 C 创建带套接字的 HTTP 服务器的教程。我正在 Windows 使用 gcc 编译器。服务器 运行s 和我什至可以点击它并在使用从 C 套接字构建的自定义客户端时取回数据。但是当我尝试 运行 命令时
"curl -o - http://127.0.0.1:8001"
连接到我的服务器时,我收到错误:
curl : Unable to read data from the transport connection: An existing connection was forcibly closed by the remote
host.
我的服务器输出显示正在尝试建立连接,但没有显示任何错误。这是我的代码..
http_server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <errno.h>
int main()
{
//open a file to server
FILE *html_data;
html_data = fopen("index.html", "r");
char response_data[1024];
fgets(response_data, 1024, html_data);
char http_header[2048] = "HTTP/1.1 200 OK\r\n\r\n";
strcat(http_header, response_data);
//create a socket
int server_socket;
server_socket = socket(AF_INET, SOCK_STREAM,0);
// specify an address for the socket
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(8001);
server_address.sin_addr.s_addr = INADDR_ANY;
//bind the socket to our specified IP and port
bind(server_socket, (struct sockaddr *) &server_address, sizeof(server_address));
listen(server_socket,5);
int client_socket;
while(1) {
client_socket = accept(server_socket, NULL, NULL);
printf("client socket response: %d\n", client_socket);
perror("socket");
send(client_socket, http_header, sizeof(http_header),0);
close(client_socket);
}
return 0;
}
index.html
<html><body>welcome to the HTTP Server!</body></html>
我认为你已经非常接近让它正常工作了。 curl
抱怨的原因是因为它希望您提供 Content-Length
header。您可以按如下方式更新现有代码来执行此操作:
char response_data[1024];
fgets(response_data, 1024, html_data);
size_t message_length = strlen(response_data);
char http_header[2048];
snprintf(http_header, sizeof(http_header), "HTTP/1.1 200 OK\r\nContent-Length: %zu\r\n\r\n", message_length);
strcat(http_header, response_data);
您还需要更新发送代码以仅发送响应字符串的长度。
send(client_socket, http_header, strlen(http_header),0);
如评论中所述,您的错误检查仍然存在一些问题,但至少有了这些更改 curl
应该很高兴。
虽然我上面提到的是满足 curl
的最小 header,但您还需要添加其他内容以使您的代码符合 Hypertext Transfer Protocol -- HTTP/1.1
Connection: close
Content-Type: text/html
我正在学习使用 C 创建带套接字的 HTTP 服务器的教程。我正在 Windows 使用 gcc 编译器。服务器 运行s 和我什至可以点击它并在使用从 C 套接字构建的自定义客户端时取回数据。但是当我尝试 运行 命令时
"curl -o - http://127.0.0.1:8001"
连接到我的服务器时,我收到错误:
curl : Unable to read data from the transport connection: An existing connection was forcibly closed by the remote
host.
我的服务器输出显示正在尝试建立连接,但没有显示任何错误。这是我的代码.. http_server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <errno.h>
int main()
{
//open a file to server
FILE *html_data;
html_data = fopen("index.html", "r");
char response_data[1024];
fgets(response_data, 1024, html_data);
char http_header[2048] = "HTTP/1.1 200 OK\r\n\r\n";
strcat(http_header, response_data);
//create a socket
int server_socket;
server_socket = socket(AF_INET, SOCK_STREAM,0);
// specify an address for the socket
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(8001);
server_address.sin_addr.s_addr = INADDR_ANY;
//bind the socket to our specified IP and port
bind(server_socket, (struct sockaddr *) &server_address, sizeof(server_address));
listen(server_socket,5);
int client_socket;
while(1) {
client_socket = accept(server_socket, NULL, NULL);
printf("client socket response: %d\n", client_socket);
perror("socket");
send(client_socket, http_header, sizeof(http_header),0);
close(client_socket);
}
return 0;
}
index.html
<html><body>welcome to the HTTP Server!</body></html>
我认为你已经非常接近让它正常工作了。 curl
抱怨的原因是因为它希望您提供 Content-Length
header。您可以按如下方式更新现有代码来执行此操作:
char response_data[1024];
fgets(response_data, 1024, html_data);
size_t message_length = strlen(response_data);
char http_header[2048];
snprintf(http_header, sizeof(http_header), "HTTP/1.1 200 OK\r\nContent-Length: %zu\r\n\r\n", message_length);
strcat(http_header, response_data);
您还需要更新发送代码以仅发送响应字符串的长度。
send(client_socket, http_header, strlen(http_header),0);
如评论中所述,您的错误检查仍然存在一些问题,但至少有了这些更改 curl
应该很高兴。
虽然我上面提到的是满足 curl
的最小 header,但您还需要添加其他内容以使您的代码符合 Hypertext Transfer Protocol -- HTTP/1.1
Connection: close
Content-Type: text/html