← Назад к вопросам

С какими сетевыми протоколами работал

1.6 Junior🔥 161 комментариев
#Опыт работы и проекты

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Сетевые протоколы в C/C++ backend-разработке

За 10+ лет я работал с множеством сетевых протоколов, от низкоуровневых до высокоуровневых. Расскажу о наиболее важных.

TCP/IP и сокеты — Foundation

TCP (Transmission Control Protocol) — это основа всей backend-разработки. Я пишу низкоуровневый код с использованием Berkeley sockets API.

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>

int server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd < 0) {
    perror("socket failed");
    return 1;
}

// Разрешить переиспользовать адрес (избежать TIME_WAIT)
int opt = 1;
setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

struct sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(8080);

if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) < 0) {
    perror("bind failed");
    return 1;
}

listen(server_fd, 5);
int client_fd = accept(server_fd, NULL, NULL);

char buffer[1024] = {0};
read(client_fd, buffer, sizeof(buffer));
write(client_fd, "Hello\n", 6);
close(client_fd);
close(server_fd);

UDP (User Datagram Protocol) — для низколатентных, connectionless приложений (игры, VoIP, DNS).

int sock = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(12345);

bind(sock, (struct sockaddr*)&addr, sizeof(addr));

char buffer[1024];
sockaddr_in client_addr;
socklen_t addr_len = sizeof(client_addr);
int n = recvfrom(sock, buffer, 1024, 0, (struct sockaddr*)&client_addr, &addr_len);
sendto(sock, "response", 8, 0, (struct sockaddr*)&client_addr, addr_len);

HTTP/HTTPS — Most Common

HTTP 1.1 — стандартный протокол для веб. Я использую libcurl или пишу простые HTTP парсеры.

#include <curl/curl.h>

CURL *curl = curl_easy_init();
if (curl) {
    curl_easy_setopt(curl, CURLOPT_URL, "https://api.example.com/users");
    curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BEARER);
    curl_easy_setopt(curl, CURLOPT_XOAUTH2_BEARER, "token_here");
    
    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
    }
    
    curl_easy_cleanup(curl);
}

HTTP/2 — бинарный протокол, мультиплексирование, push. Работаю с nghttp2 библиотекой.

HTTPS — HTTP через TLS/SSL. Обязателен для production. Использую OpenSSL.

SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
SSL_CTX_load_verify_locations(ctx, "/etc/ssl/certs/ca-bundle.crt", NULL);

SSL *ssl = SSL_new(ctx);
SSL_set_connect_state(ssl);
SSL_do_handshake(ssl);

WebSocket — Real-time Communication

Для real-time приложений (чаты, уведомления, live updates) использую WebSocket.

// libwebsockets — популярная C библиотека
#include <libwebsockets.h>

struct lws_protocols protocols[] = {
    {
        "my-protocol",
        callback_function,  // Вызывается при connect, message, close
        0,
        1024,
    },
    { NULL, NULL, 0, 0 }
};

struct lws_context_creation_info info = {0};
info.port = 8080;
info.protocols = protocols;
info.options = LWS_SERVER_OPTION_VALIDATE_UTF8;

struct lws_context *context = lws_create_context(&info);
// ...
while (n >= 0) {
    lws_service(context, 50);
}

DNS — Name Resolution

Для разрешения имён хостов использую getaddrinfo():

#include <netdb.h>

struct addrinfo hints = {0};
hints.ai_family = AF_UNSPEC;     // IPv4 или IPv6
hints.ai_socktype = SOCK_STREAM;

struct addrinfo *result;
int status = getaddrinfo("example.com", "80", &hints, &result);

if (status != 0) {
    fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
    return 1;
}

for (struct addrinfo *p = result; p != NULL; p = p->ai_next) {
    int sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
    if (sockfd >= 0 && connect(sockfd, p->ai_addr, p->ai_addrlen) == 0) {
        // Успешное подключение
        break;
    }
    close(sockfd);
}

freeaddrinfo(result);

gRPC — Modern RPC Framework

Для микросервис-архитектуры использую gRPC (Protocol Buffers + HTTP/2).

// hello.proto
service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}
// server
class GreeterServiceImpl : public Greeter::Service {
    Status SayHello(ServerContext* context, 
                    const HelloRequest* request,
                    HelloReply* reply) override {
        reply->set_message("Hello " + request->name());
        return Status::OK;
    }
};

MQTT — IoT and Message Brokers

Для IoT и publish-subscribe паттернов использую MQTT.

#include <mosquitto.h>

mosquitto_lib_init();
struct mosquitto *mosq = mosquitto_new(NULL, true, NULL);

mosquitto_connect(mosq, "broker.example.com", 1883, 60);
mosquitto_publish(mosq, NULL, "sensors/temp", 11, "22.5", 0, false);
mosquitto_subscribe(mosq, NULL, "sensors/#");

while (true) {
    mosquitto_loop(mosq, -1, 1);
}

mosquitto_destroy(mosq);
mosquitto_lib_cleanup();

AMQP — Advanced Message Queuing Protocol

Для RabbitMQ использую librabbitmq.

#include <amqp.h>

amqp_connection_state_t conn = amqp_new_connection();
amqp_socket_t *socket = amqp_tcp_socket_new(conn);
amqp_socket_open(socket, "localhost", 5672);
amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest");

amqp_channel_open(conn, 1);
amqp_queue_declare(conn, 1, amqp_cstring_bytes("my_queue"), 0, 1, 0, 0, amqp_empty_table);

amqp_basic_publish(conn, 1, amqp_cstring_bytes("amq.direct"), 
                   amqp_cstring_bytes("routing_key"), 0, 0,
                   &properties, amqp_cstring_bytes("message body"));

TLS/SSL — Security

Для шифрованного соединения используюOpenSSL, mbedTLS или Boost.Asio с SSL.

// Простой HTTPS клиент с libcurl (использует OpenSSL внутри)
curl_easy_setopt(curl, CURLOPT_URL, "https://api.example.com");
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L);
curl_easy_setopt(curl, CURLOPT_CAINFO, "/etc/ssl/certs/ca-bundle.crt");

QUIC — Modern Replacement for TCP

Новое поколение протокола, улучшает latency. Работаю с libquiche.

Практический выбор

В разных сценариях:

СценарийПротоколПричина
REST APIHTTP/1.1, HTTP/2Стандарт, browser-friendly
Real-timeWebSocketДвусторонняя коммуникация
МикросервисыgRPCБыстро, типизировано
IoTMQTTЛёгкий, low-power
ОчередиAMQPНадёжная доставка
ИгрыUDPНизкая latency
ШифрованиеTLS/SSLБезопасность

Вывод

Хороший backend-разработчик должен понимать все эти протоколы на практическом уровне. Не обязательно помнить API каждой библиотеки, но понимать, когда и что использовать — критично. В 10+ лет я встречался со всеми этими протоколами в production системах.