In diesem Blogbeitrag untersuchen wir, wie man einen einfachen TCP-Server in C erstellt, der HTML-Dateien bereitstellen kann. Wir werden den Code aufschlüsseln, erklären, wie er funktioniert, und zukünftige Pläne zur Verbesserung dieses Projekts besprechen. Dies ist ein hervorragendes Beispiel dafür, wie Sie in C „einfach Dinge erledigen“ können, ohne den Prozess zu verkomplizieren!
Das Ziel dieses Projekts ist die Implementierung eines einfachen TCP-Servers, der auf Clientverbindungen wartet und auf Anfrage HTML-Dateien bereitstellt. Der Server verarbeitet Client-Anfragen, liest die angegebene HTML-Datei und sendet den Inhalt als HTTP-Antwort an den Client zurück.
Um unseren Code zu organisieren, strukturieren wir das Projekt wie folgt:
tcp_server_c/ ├── CMakeLists.txt # Build configuration ├── include/ │ ├── server.h # Main server header file │ ├── html_serve.h # Header for serve_html function │ ├── request_handler.h # Header for handle_client function │ └── socket_utils.h # Header for socket utility functions ├── src/ │ ├── server.c # Main server program │ ├── html_serve.c # serve_html function │ ├── request_handler.c # handle_client function │ └── socket_utils.c # Utility functions for socket operations └── README.md # Project documentation
Erstellen wir zunächst eine Dienstprogrammdatei für die Socket-Initialisierung. Dadurch wird sichergestellt, dass unser Hauptservercode sauber und fokussiert bleibt.
include/socket_utils.h
#ifndef SOCKET_UTILS_H #define SOCKET_UTILS_H #include <arpa/inet.h> int initialize_server(struct sockaddr_in* address); #endif
src/socket_utils.c
#include "socket_utils.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define PORT 8080 int initialize_server(struct sockaddr_in* address) { int server_fd; int opt = 1; if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("Socket failed!"); return -1; } if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt)) != 0) { perror("setsockopt failed"); close(server_fd); return -1; } address->sin_family = AF_INET; address->sin_addr.s_addr = INADDR_ANY; address->sin_port = htons(PORT); if (bind(server_fd, (struct sockaddr*)address, sizeof(*address)) < 0) { perror("Bind failed!"); close(server_fd); return -1; } if (listen(server_fd, 3) < 0) { perror("Listen failed!"); close(server_fd); return -1; } return server_fd; }
Als nächstes erstellen wir eine Funktion zum Bereitstellen von HTML-Dateien. Diese Funktion liest den Inhalt einer HTML-Datei und gibt sie an den Aufrufer zurück.
include/html_server.h
#ifndef HTML_SERVER_H #define HTML_SERVER_H char* serve_html(const char* filename); #endif
src/html_server.c
#include "html_server.h" #include <stdio.h> #include <stdlib.h> #include <string.h> char* serve_html(const char* filename) { FILE* file = fopen(filename, "r"); if (!file) { perror("Error opening file"); return NULL; } fseek(file, 0, SEEK_END); long length = ftell(file); fseek(file, 0, SEEK_SET); char* buffer = malloc(length + 1); if (!buffer) { perror("Error allocating memory"); fclose(file); return NULL; } fread(buffer, 1, length, file); buffer[length] = '<pre class="brush:php;toolbar:false">#ifndef REQUEST_HANDLER_H #define REQUEST_HANDLER_H #include <sys/socket.h> void handle_client(int new_socket); #endif
Jetzt implementieren wir die Logik zur Bearbeitung eingehender Kundenanfragen.
include/request_handler.h
#include "request_handler.h" #include "html_server.h" #include <stdio.h> #include <string.h> #include <unistd.h> #define BUFFER_SIZE 1024 void handle_client(int new_socket) { char buffer[BUFFER_SIZE] = { 0 }; read(new_socket, buffer, BUFFER_SIZE); // Serve the HTML file char* html_content = serve_html("../html/index.html"); if (html_content) { write(new_socket, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n", 48); write(new_socket, html_content, strlen(html_content)); } else { const char* not_found_response = "HTTP/1.1 404 Not Found\r\nContent-Type: text/html\r\n\r\n<h1>404 Not Found</h1>"; write(new_socket, not_found_response, strlen(not_found_response)); } free(html_content); close(new_socket); // Close the connection with the current client }
src/request_handler.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <unistd.h> #include "socket_utils.h" #include "request_handler.h" int main() { int server_fd, new_socket; struct sockaddr_in address; int addrlen = sizeof(address); server_fd = initialize_server(&address); if (server_fd == -1) { return EXIT_FAILURE; } printf("Server listening on port: 8080\n"); while (1) { if ((new_socket = accept(server_fd, (struct sockaddr*)&address, (socklen_t*)&addrlen)) < 0) { perror("Connection not accepted!"); continue; } handle_client(new_socket); // Handle the client request } close(server_fd); return 0; }
Zum Schluss fügen wir alles in der Hauptdatei zusammen.
src/main.c
Für die Zukunft planen wir die Implementierung mehrerer Verbesserungen und Funktionen:
Dieses einfache TCP-Serverprojekt dient als grundlegendes Beispiel für die Erstellung eines Webservers in C und demonstriert die Leistungsfähigkeit und Einfachheit der Sprache. Indem wir auf dieser Grundlage aufbauen, können wir ausgefeiltere Funktionen entwickeln und die Leistung verbessern, was es zu einer robusten Lösung für die Bereitstellung von Webinhalten macht.
Sie können den vollständigen Quellcode finden und zum Projekt auf GitHub beitragen: GitHub Repository Link.
Sie können gerne Feedback geben, Fragen stellen oder Ihre Ideen für zukünftige Verbesserungen einbringen!
Das obige ist der detaillierte Inhalt vonErstellen eines einfachen TCP-Servers in C. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!