С какими сетевыми протоколами работал
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Сетевые протоколы в 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 API | HTTP/1.1, HTTP/2 | Стандарт, browser-friendly |
| Real-time | WebSocket | Двусторонняя коммуникация |
| Микросервисы | gRPC | Быстро, типизировано |
| IoT | MQTT | Лёгкий, low-power |
| Очереди | AMQP | Надёжная доставка |
| Игры | UDP | Низкая latency |
| Шифрование | TLS/SSL | Безопасность |
Вывод
Хороший backend-разработчик должен понимать все эти протоколы на практическом уровне. Не обязательно помнить API каждой библиотеки, но понимать, когда и что использовать — критично. В 10+ лет я встречался со всеми этими протоколами в production системах.