1、发送HTTP响应的函数
用于发送HTTP响应的函数。它向客户端发送一个包含状态行、响应头和HTML内容的HTTP响应。
HTTP/1.1 200 OK
:表示服务器处理请求成功,返回状态码 200。
Content-Type: text/html
:表示返回的数据类型是HTML格式。
Content-Length: 51
:表示HTML内容的长度为 51 字节。
<html>...</html>
:HTML内容,表示服务器返回的页面内容是一个简单的HTML页面。
write()
向客户端发送数据。client_socket 是与客户端通信的套接字。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8080 // 服务器监听的端口号
#define BUFFER_SIZE 1024
// 发送HTTP响应
void send_http_response(int client_socket) {
char response[] =
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n"
"Content-Length: 51\r\n"
"\r\n"
"<html><body><h1>Hello, C HTTP Server!</h1></body></html>";
write(client_socket, response, sizeof(response) - 1);
}
2、创建绑定服务器套接字
socket()
创建一个套接字。AF_INET
是指定使用IPv4地址。SOCK_STREAM
是指定使用TCP连接。0
是协议自动选择为TCP。如果 socket()
返回 -1
,表示创建失败,此时程序调用 perror()
输出错误信息并退出。bind()
将套接字与服务器的IP地址和端口号绑定。如果绑定失败,程序输出错误信息并退出。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8080 // 服务器监听的端口号
#define BUFFER_SIZE 1024
int main() {
int server_socket, client_socket;
struct sockaddr_in server_addr, client_addr;
socklen_t client_addr_len = sizeof(client_addr);
char buffer[BUFFER_SIZE];
// 创建服务器套接字
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket == -1) {
perror("无法创建套接字");
exit(EXIT_FAILURE);
}
// 设置服务器地址
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY; // 监听所有网络接口
server_addr.sin_port = htons(PORT); // 端口号
// 绑定套接字到指定的端口
if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
perror("绑定失败");
close(server_socket);
exit(EXIT_FAILURE);
}
// 监听客户端连接请求
if (listen(server_socket, 10) == -1) {
perror("监听失败");
close(server_socket);
exit(EXIT_FAILURE);
}
printf("服务器启动,正在监听端口 %d...\n", PORT);
}
3、接受读取客户端请并响应
accept()
接受客户端连接,并为该连接创建一个新的套接字 client_socket
。如果接收失败,程序输出错误信息并继续等待下一个连接。调用之前定义的send_http_response()
函数,向客户端发送HTTP响应。
while (1) {
// 接受客户端连接
client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_addr_len);
if (client_socket == -1) {
perror("接受客户端连接失败");
continue;
}
// 清空缓冲区,接收客户端发送的数据
memset(buffer, 0, BUFFER_SIZE);
read(client_socket, buffer, BUFFER_SIZE - 1);
printf("接收到的请求:\n%s\n", buffer);
// 发送HTTP响应
send_http_response(client_socket);
// 关闭客户端连接
close(client_socket);
}
// 关闭服务器套接字
close(server_socket);
4、完整代码
一个简易的HTTP服务器,可以根据自己的需求进行扩展和完善。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8080 // 服务器监听的端口号
#define BUFFER_SIZE 1024
// 发送HTTP响应
void send_http_response(int client_socket) {
char response[] =
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n"
"Content-Length: 51\r\n"
"\r\n"
"<html><body><h1>Hello, C HTTP Server!</h1></body></html>";
write(client_socket, response, sizeof(response) - 1);
}
int main() {
int server_socket, client_socket;
struct sockaddr_in server_addr, client_addr;
socklen_t client_addr_len = sizeof(client_addr);
char buffer[BUFFER_SIZE];
// 创建服务器套接字
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket == -1) {
perror("无法创建套接字");
exit(EXIT_FAILURE);
}
// 设置服务器地址
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY; // 监听所有网络接口
server_addr.sin_port = htons(PORT); // 端口号
// 绑定套接字到指定的端口
if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
perror("绑定失败");
close(server_socket);
exit(EXIT_FAILURE);
}
// 监听客户端连接请求
if (listen(server_socket, 10) == -1) {
perror("监听失败");
close(server_socket);
exit(EXIT_FAILURE);
}
printf("服务器启动,正在监听端口 %d...\n", PORT);
// 主循环,处理客户端连接
while (1) {
// 接受客户端连接
client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_addr_len);
if (client_socket == -1) {
perror("接受客户端连接失败");
continue;
}
// 清空缓冲区,接收客户端发送的数据
memset(buffer, 0, BUFFER_SIZE);
read(client_socket, buffer, BUFFER_SIZE - 1);
printf("接收到的请求:\n%s\n", buffer);
// 发送HTTP响应
send_http_response(client_socket);
// 关闭客户端连接
close(client_socket);
}
// 关闭服务器套接字
close(server_socket);
return 0;
}