"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Construindo um servidor TCP simples em C

Construindo um servidor TCP simples em C

Publicado em 2024-11-08
Navegar:911

Building a Simple TCP Server in C

Nesta postagem do blog, exploraremos como criar um servidor TCP simples em C que pode servir arquivos HTML. Detalharemos o código, explicaremos como ele funciona e discutiremos planos futuros para aprimorar este projeto. Este é um excelente exemplo de como você pode "simplesmente fazer coisas" em C sem complicar demais o processo!

Visão geral do projeto

O objetivo deste projeto é implementar um servidor TCP básico que escuta conexões de clientes e fornece arquivos HTML mediante solicitação. O servidor tratará as solicitações do cliente, lerá o arquivo HTML especificado e enviará o conteúdo de volta ao cliente como uma resposta HTTP.

? Continue a conversa no Twitter(X): @trish_07

? Repositório GitHub: Explore o repositório de projetos do servidor TCP

Estrutura do Projeto

Para organizar nosso código, estruturaremos o projeto da seguinte forma:

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

Detalhamento do código

1. Utilitários de soquete

Primeiro, vamos criar um arquivo utilitário para lidar com a inicialização do soquete. Isso garantirá que o código do nosso servidor principal permaneça limpo e focado.

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. Funcionalidade de serviço HTML

A seguir, criaremos uma função para servir arquivos HTML. Esta função irá ler o conteúdo de um arquivo HTML e retorná-lo ao chamador.

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. Tratamento de solicitações de clientes

Agora, vamos implementar a lógica para lidar com solicitações recebidas de clientes.

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. Lógica do Servidor Principal

Finalmente, vamos juntar tudo no arquivo principal.

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



Planos futuros

No futuro, há vários aprimoramentos e recursos que planejamos implementar:

  1. Suporte multi-threading: Para lidar com múltiplas conexões de clientes simultaneamente, apresentaremos recursos de threading para melhorar a eficiência do servidor.
  2. Serviço de conteúdo dinâmico: implemente funcionalidade para fornecer conteúdo dinâmico integrando-o a um mecanismo de modelagem leve.
  3. Registro: adicione um mecanismo de registro para rastrear solicitações, erros e desempenho do servidor.
  4. Recursos de segurança: explore a adição de suporte HTTPS e validação de entrada para aumentar a segurança.
  5. Tratamento de erros aprimorado: Implemente melhor tratamento de erros para vários cenários, como arquivo não encontrado, sobrecarga do servidor, etc.

Conclusão

Este projeto simples de servidor TCP serve como um exemplo básico de como criar um servidor web em C, demonstrando o poder e a simplicidade da linguagem. Com base nesta base, podemos desenvolver recursos mais sofisticados e melhorar o desempenho, tornando-a uma solução robusta para servir conteúdo da web.

Você pode encontrar o código-fonte completo e contribuir com o projeto no GitHub: GitHub Repository Link.

Sinta-se à vontade para fornecer feedback, fazer perguntas ou contribuir com suas ideias para melhorias futuras!


Declaração de lançamento Este artigo foi reproduzido em: https://dev.to/trish_07/building-a-simple-tcp-server-in-c-2h85 Se houver alguma violação, entre em contato com [email protected] para excluí-la
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3