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 request
    pid_t pid = fork();
    if (pid < 0) {
        perror("Fork failed");
        close(client_socket);
        continue;
    } else if (pid == 0) {
        // Child process
        close(server_socket); // Close server socket in child process

        handle_client(client_socket);

        close(client_socket);
        exit(EXIT_SUCCESS);
    } else {
        // Parent process
        close(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 path
        file_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 connection
    if ((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 client
    if (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 automatically
    pthread_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 debug
    printf("Received request:\n%s\n", buffer);
    
    // Parse the HTTP request
    // For simplicity, assume the request is a GET or POST request
    if (strstr(buffer, "GET") != NULL) {
        if (strstr(buffer, "GET /image.jpg") != NULL) {
            // Serve the image file
            FILE *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 chunks
                while ((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 page
            sprintf(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 requests
            sprintf(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 requests
        char *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 data
        int 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 received
        sprintf(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 requests
        sprintf(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;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值