linux 多进程搭建webserver
服务器
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define PORT 8080
#define WEB_ROOT “./www”
void handle_client(int client_socket);
int main() {
int server_socket, client_socket;
struct sockaddr_in server_addr, client_addr;
socklen_t addr_size;
// Create socket
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket < 0) {perror("Socket creation failed");exit(EXIT_FAILURE);
}// Prepare the server sockaddr structure
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(PORT);// Bind socket to address
if (bind(server_socket, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) {perror("Binding failed");exit(EXIT_FAILURE);
}// Listen for incoming connections
if (listen(server_socket, 10) < 0) {perror("Listen failed");exit(EXIT_FAILURE);
}printf("Server listening on port %d...\n", PORT);// Accept incoming connections
while (1) {addr_size = sizeof(client_addr);client_socket = accept(server_socket, (struct sockaddr *) &client_addr, &addr_size);if (client_socket < 0) {perror("Accept failed");continue;}// Fork a child process to handle the client requestpid_t pid = fork();if (pid < 0) {perror("Fork failed");close(client_socket);continue;} else if (pid == 0) {// Child processclose(server_socket); // Close server socket in child processhandle_client(client_socket);close(client_socket);exit(EXIT_SUCCESS);} else {// Parent processclose(client_socket); // Close client socket in parent process}
}close(server_socket);return 0;
}
void handle_client(int client_socket) {
char buffer[1024] = {0};
char response[2048] = {0};
int read_size;
char *file_path;
FILE *fp;
// Receive client request
read_size = read(client_socket, buffer, sizeof(buffer));
if (read_size <= 0) {perror("Read failed");return;
}// Extract the requested file path from the HTTP request
if (strncmp(buffer, "GET ", 4) == 0) {char *start = buffer + 4;char *end = strstr(start, " ");if (end != NULL) {*end = '\0'; // Null-terminate the file pathfile_path = start;} else {perror("Invalid HTTP request");return;}
} else {perror("Unsupported HTTP method");return;
}// Construct full file path (prepend ./www)
char full_path[256];
snprintf(full_path, sizeof(full_path), "%s%s", WEB_ROOT, file_path);// Open requested file
fp = fopen(full_path, "rb");
if (fp == NULL) {perror("File open failed");return;
}// Prepare HTTP response
snprintf(response, sizeof(response),"HTTP/1.1 200 OK\r\n""Content-Type: text/html\r\n\r\n");// Send HTTP response header
write(client_socket, response, strlen(response));// Send file contents
while ((read_size = fread(buffer, 1, sizeof(buffer), fp)) > 0) {write(client_socket, buffer, read_size);
}fclose(fp);
}
客户端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define SERVER_IP “192.168.15.3”
#define SERVER_PORT 8080
int main() {
int client_socket;
struct sockaddr_in server_addr;
char request[1024];
char response[2048];
int bytes_received;
// Create socket
client_socket = socket(AF_INET, SOCK_STREAM, 0);
if (client_socket < 0) {perror("Socket creation failed");exit(EXIT_FAILURE);
}// Prepare server sockaddr structure
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);// Connect to server
if (connect(client_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {perror("Connection failed");exit(EXIT_FAILURE);
}// Prepare HTTP GET request
snprintf(request, sizeof(request), "GET /index.html HTTP/1.1\r\nHost: %s:%d\r\nConnection: close\r\n\r\n", SERVER_IP, SERVER_PORT);// Send HTTP GET request to server
if (send(client_socket, request, strlen(request), 0) < 0) {perror("Send failed");exit(EXIT_FAILURE);
}// Receive and display server response
printf("Response from server:\n");
while ((bytes_received = recv(client_socket, response, sizeof(response), 0)) > 0) {fwrite(response, 1, bytes_received, stdout);
}
printf("\n");// Close socket
close(client_socket);return 0;
}
加入post
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <fcntl.h>
#define PORT 8080
#define MAX_CONNECTIONS 10
void *handle_client(void *socket_desc);
int main() {
int server_fd, new_socket, c;
struct sockaddr_in address;
int opt = 1;
pthread_t thread_id;
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("Socket creation failed");exit(EXIT_FAILURE);
}// Forcefully attaching socket to the port 8080
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {perror("Setsockopt failed");exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);// Binding the socket to the address
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {perror("Bind failed");exit(EXIT_FAILURE);
}// Listening for connections
if (listen(server_fd, MAX_CONNECTIONS) < 0) {perror("Listen failed");exit(EXIT_FAILURE);
}printf("Server listening on port %d...\n", PORT);while (1) {// Accept incoming connectionif ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&c)) < 0) {perror("Accept failed");exit(EXIT_FAILURE);}printf("New connection accepted\n");// Create a new thread for handling the clientif (pthread_create(&thread_id, NULL, handle_client, (void *)&new_socket) < 0) {perror("Thread creation failed");exit(EXIT_FAILURE);}// Detach the thread, so its resources can be cleaned up automaticallypthread_detach(thread_id);
}return 0;
}
void *handle_client(void *socket_desc) {
int client_socket = *(int *)socket_desc;
char buffer[1024] = {0};
char response[1024] = {0};
int read_size;
// Receive request from client
if ((read_size = recv(client_socket, buffer, 1024, 0)) > 0) {// Print received request for debugprintf("Received request:\n%s\n", buffer);// Parse the HTTP request// For simplicity, assume the request is a GET or POST requestif (strstr(buffer, "GET") != NULL) {if (strstr(buffer, "GET /image.jpg") != NULL) {// Serve the image fileFILE *fp = fopen("image.jpg", "rb");if (fp == NULL) {perror("Failed to open image file");sprintf(response, "HTTP/1.1 404 Not Found\nContent-Type: text/html\n\n<h1>404 Not Found</h1>");} else {fseek(fp, 0L, SEEK_END);int file_size = ftell(fp);fseek(fp, 0L, SEEK_SET);sprintf(response, "HTTP/1.1 200 OK\nContent-Type: image/jpeg\nContent-Length: %d\n\n", file_size);send(client_socket, response, strlen(response), 0);// Send file contents in chunkswhile ((read_size = fread(buffer, 1, sizeof(buffer), fp)) > 0) {send(client_socket, buffer, read_size, 0);}fclose(fp);}} else if (strstr(buffer, "GET /") != NULL) {// Serve a simple HTML pagesprintf(response, "HTTP/1.1 200 OK\nContent-Type: text/html\n\n<h1>Hello, World!</h1>");send(client_socket, response, strlen(response), 0);} else {// Handle other GET requestssprintf(response, "HTTP/1.1 404 Not Found\nContent-Type: text/html\n\n<h1>404 Not Found</h1>");send(client_socket, response, strlen(response), 0);}} else if (strstr(buffer, "POST") != NULL) {// Handle POST requestschar *content_length_header = strstr(buffer, "Content-Length:");int content_length = 0;if (content_length_header != NULL) {content_length = atoi(content_length_header + 15); // Skip "Content-Length:" to get the value}// Read POST dataint total_read = 0;while ((read_size = recv(client_socket, buffer, 1024, 0)) > 0) {total_read += read_size;if (total_read >= content_length) {break;}}// Process the received data (in buffer)// Here, you can handle the POST data according to your application's logic// For simplicity, we just send a response indicating the data was receivedsprintf(response, "HTTP/1.1 200 OK\nContent-Type: text/html\n\n<h1>POST request received!</h1>");send(client_socket, response, strlen(response), 0);} else {// Handle unsupported requestssprintf(response, "HTTP/1.1 400 Bad Request\nContent-Type: text/html\n\n<h1>400 Bad Request</h1>");send(client_socket, response, strlen(response), 0);}
}// Close the socket and exit the thread
close(client_socket);
printf("Connection closed\n");
return NULL;
}