このブログ投稿では、HTML ファイルを提供できる単純な TCP サーバーを C で作成する方法を検討します。コードを分解し、それがどのように機能するかを説明し、このプロジェクトを強化するための将来の計画について話し合います。これは、プロセスを過度に複雑にすることなく、C で「単に処理する」方法を示す優れた例です。
このプロジェクトの目標は、クライアント接続をリッスンし、要求に応じて HTML ファイルを提供する基本的な TCP サーバーを実装することです。サーバーはクライアントのリクエストを処理し、指定された HTML ファイルを読み取り、その内容を HTTP 応答としてクライアントに送り返します。
コードを整理するために、プロジェクトを次のように構造化します。
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
まず、ソケットの初期化を処理するユーティリティ ファイルを作成しましょう。これにより、メインサーバーのコードがクリーンで集中した状態に保たれます。
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; }
次に、HTML ファイルを提供する関数を作成します。この関数は、HTML ファイルの内容を読み取り、呼び出し元に返します。
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'; // Null-terminate the buffer fclose(file); return buffer; }
次に、受信クライアントリクエストを処理するロジックを実装しましょう。
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; }
最後に、すべてをメイン ファイルにまとめましょう。
src/main.c
今後、いくつかの機能強化と機能の実装を予定しています。
この単純な TCP サーバー プロジェクトは、C で Web サーバーを作成する方法の基本的な例として機能し、C 言語の能力とシンプルさを実証します。この基盤の上に構築することで、より洗練された機能を開発し、パフォーマンスを向上させ、Web コンテンツを提供するための堅牢なソリューションにすることができます。
完全なソース コードを見つけて、GitHub でプロジェクトに貢献できます: GitHub リポジトリ リンク。
お気軽にフィードバックを提供したり、質問したり、将来の機能強化のためのアイデアを提供してください!
以上がC で単純な TCP サーバーを構築するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。