「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > C で単純な TCP サーバーを構築する

C で単純な TCP サーバーを構築する

2024 年 11 月 8 日に公開
ブラウズ:966

Building a Simple TCP Server in C

このブログ投稿では、HTML ファイルを提供できる単純な TCP サーバーを C で作成する方法を検討します。コードを分解し、それがどのように機能するかを説明し、このプロジェクトを強化するための将来の計画について話し合います。これは、プロセスを過度に複雑にすることなく、C で「単に処理する」方法を示す優れた例です。

プロジェクト概要

このプロジェクトの目標は、クライアント接続をリッスンし、要求に応じて HTML ファイルを提供する基本的な TCP サーバーを実装することです。サーバーはクライアントのリクエストを処理し、指定された HTML ファイルを読み取り、その内容を HTTP 応答としてクライアントに送り返します。

? Twitter(X) で会話を続けましょう: @trish_07

? GitHub リポジトリ: TCP サーバー プロジェクト リポジトリを探索する

プロジェクトの構造

コードを整理するために、プロジェクトを次のように構造化します:

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

コードの内訳

1. ソケットユーティリティ

まず、ソケットの初期化を処理するユーティリティ ファイルを作成しましょう。これにより、メイン サーバー コードがクリーンで集中した状態に保たれます。

include/socket_utils.h

#ifndef SOCKET_UTILS_H
#define SOCKET_UTILS_H

#include 

int initialize_server(struct sockaddr_in* address);

#endif

src/socket_utils.c

#include "socket_utils.h"
#include 
#include 
#include 
#include 

#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)) 



2. HTML 配信機能

次に、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 
#include 
#include 

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] = '\0'; // Null-terminate the buffer

    fclose(file);
    return buffer;
}

3. クライアントリクエストの処理

次に、受信クライアントリクエストを処理するロジックを実装しましょう。

include/request_handler.h

#ifndef REQUEST_HANDLER_H
#define REQUEST_HANDLER_H

#include 

void handle_client(int new_socket);

#endif

src/request_handler.c

#include "request_handler.h"
#include "html_server.h"
#include 
#include 
#include 

#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

404 Not Found

"; write(new_socket, not_found_response, strlen(not_found_response)); } free(html_content); close(new_socket); // Close the connection with the current client }

4. メインサーバーロジック

最後に、すべてをメイン ファイルにまとめましょう。

src/main.c

#include 
#include 
#include 
#include 
#include 
#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)) 



今後の予定

今後、実装する予定の機能強化や機能がいくつかあります:

  1. マルチスレッドのサポート: 複数のクライアント接続を同時に処理するために、サーバーの効率を向上させるスレッド機能を導入します。
  2. 動的コンテンツの提供: 軽量のテンプレート エンジンと統合することで、動的コンテンツを提供する機能を実装します。
  3. ロギング: リクエスト、エラー、サーバーのパフォーマンスを追跡するためのロギング メカニズムを追加します。
  4. セキュリティ機能: セキュリティを強化するための HTTPS サポートと入力検証の追加を検討します。
  5. エラー処理の改善: ファイルが見つからない、サーバーの過負荷など、さまざまなシナリオに対してより適切なエラー処理を実装します。

結論

この単純な TCP サーバー プロジェクトは、C で Web サーバーを作成する方法の基本的な例として機能し、C 言語の能力とシンプルさを実証します。この基盤に基づいて構築することで、より洗練された機能を開発し、パフォーマンスを向上させ、Web コンテンツを提供するための堅牢なソリューションにすることができます。

完全なソース コードを見つけて、GitHub でプロジェクトに貢献できます: GitHub リポジトリ リンク。

お気軽にフィードバックを提供したり、質問したり、将来の機能強化に向けたアイデアを投稿してください。


リリースステートメント この記事は次の場所に転載されています: https://dev.to/trish_07/building-a-simple-tcp-server-in-c-2h85 侵害がある場合は、[email protected] に連絡して削除してください。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3