C 语言实现 HTTP 服务器 - 解析多请求行消息
#include <netinet/in.h> #include <netinet/ip.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <unistd.h>
#define ECHO_PORT 9999 #define BUF_SIZE 4096
int close_socket(int sock) { if (close(sock)) { fprintf(stderr, "Failed closing socket.\n"); return 1; } return 0; }
int main(int argc, char* argv[]) { int sock, client_sock; ssize_t readret; socklen_t cli_size; struct sockaddr_in addr, cli_addr; char buf[BUF_SIZE];
fprintf(stdout, "----- Echo Server -----\n");
/* all networked programs must create a socket */
if ((sock = socket(PF_INET, SOCK_STREAM, 0)) == -1)
{
fprintf(stderr, "Failed creating socket.\n");
return EXIT_FAILURE;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(ECHO_PORT);
addr.sin_addr.s_addr = INADDR_ANY;
/* servers bind sockets to ports---notify the OS they accept connections */
if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)))
{
close_socket(sock);
fprintf(stderr, "Failed binding socket.\n");
return EXIT_FAILURE;
}
if (listen(sock, 5))
{
close_socket(sock);
fprintf(stderr, "Error listening on socket.\n");
return EXIT_FAILURE;
}
/* finally, loop waiting for input and then write it back */
while (1)
{
cli_size = sizeof(cli_addr);
if ((client_sock = accept(sock, (struct sockaddr *) &cli_addr,
&cli_size)) == -1)
{
close(sock);
fprintf(stderr, "Error accepting connection.\n");
return EXIT_FAILURE;
}
readret = 0;
while((readret = recv(client_sock, buf, BUF_SIZE, 0)) >= 1)
{
// 解析消息
char method[BUF_SIZE], uri[BUF_SIZE], version[BUF_SIZE];
int n = sscanf(buf, "%s %s %s", method, uri, version);
if (n != 3 || strcmp(version, "HTTP/1.1") != 0) {
// 格式错误
char response[] = "HTTP/1.1 400 Bad request\r\n\r\n";
send(client_sock, response, strlen(response), 0);
break;
} else if (strcmp(method, "GET") == 0 || strcmp(method, "HEAD") == 0 || strcmp(method, "POST") == 0) {
// Echo
send(client_sock, buf, strlen(buf), 0);
memset(buf, 0, BUF_SIZE);
continue;
} else {
// 没实现
char response[] = "HTTP/1.1 501 Not Implemented\r\n\r\n";
send(client_sock, response, strlen(response), 0);
break;
}
}
if (readret == -1)
{
close_socket(client_sock);
close_socket(sock);
fprintf(stderr, "Error reading from client socket.\n");
return EXIT_FAILURE;
}
if (close_socket(client_sock))
{
close_socket(sock);
fprintf(stderr, "Error closing client socket.\n");
return EXIT_FAILURE;
}
}
close_socket(sock);
return EXIT_SUCCESS;
}
原文地址: https://www.cveoy.top/t/topic/n37z 著作权归作者所有。请勿转载和采集!