Работали ли вы с TCP?

Ответ

Да, я разрабатывал сетевые приложения с использованием TCP-сокетов в C++. TCP (Transmission Control Protocol) — это надежный потоковый протокол с установкой соединения, гарантирующий порядок и доставку пакетов.

Пример базового TCP-клиента на C++ с использованием Berkeley sockets:

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

int main() {
    // Создание сокета
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) { /* обработка ошибки */ }

    // Настройка адреса сервера
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(8080);
    inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr);

    // Установка соединения
    if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
        // обработка ошибки
    }

    // Отправка данных
    const char* msg = "Hello, server!";
    send(sockfd, msg, strlen(msg), 0);

    // Получение ответа (упрощённо, в реальности нужен цикл)
    char buffer[256];
    ssize_t bytes_read = recv(sockfd, buffer, sizeof(buffer)-1, 0);
    if (bytes_read > 0) {
        buffer[bytes_read] = '';
        // обработка полученных данных
    }
    close(sockfd);
    return 0;
}

В реальных проектах я использовал неблокирующие сокеты с мультиплексированием (select/poll/epoll в Linux или kqueue в BSD) для создания асинхронных серверов, способных обрабатывать множество соединений в одном потоке.

Ответ 18+ 🔞

А, сетевое программирование на сокетах! Да, хуй с горы, я этим тоже баловался. TCP — это, конечно, надёжная штука, как швейцарские часы, только если всё правильно настроить, а иначе — пиздец рулю.

Смотри, вот тебе простой пример клиента, который пытается достучаться до сервера. Выглядит всё вроде просто, но тут подводных камней — овердохуища. Один неверный байт — и всё, приехали, соединение накрылось медным тазом.

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

int main() {
    // Создание сокета
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) { /* обработка ошибки */ }

    // Настройка адреса сервера
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(8080);
    inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr);

    // Установка соединения
    if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
        // обработка ошибки
    }

    // Отправка данных
    const char* msg = "Hello, server!";
    send(sockfd, msg, strlen(msg), 0);

    // Получение ответа (упрощённо, в реальности нужен цикл)
    char buffer[256];
    ssize_t bytes_read = recv(sockfd, buffer, sizeof(buffer)-1, 0);
    if (bytes_read > 0) {
        buffer[bytes_read] = '';
        // обработка полученных данных
    }
    close(sockfd);
    return 0;
}

Вот смотри на этот код и думаешь: «Ну ёпта, что тут сложного?». А сложность начинается, когда этот recv зависает намертво, потому что сервер — пидарас шерстяной — молчит как партизан. Или когда connect падает, потому что на том конце просто никто не слушает порт. Доверия к сети — ноль ебать, всегда нужно быть готовым, что всё пойдёт по пизде.

А в реальных-то проектах, чувак, этот примитив не катит. Когда нужно держать сотни или тысячи соединений в одном потоке, тут начинается настоящий цирк. Начинаешь юзать неблокирующие сокеты и эти все select, poll, epoll под Linux. Э, бошка, думай! Это уже не просто «отправил-получил», а нужно следить, какой сокет готов к чтению, какой к записи, где таймаут, где соединение отвалилось. Одна ошибка в логике — и сервер превращается в тыкву, которая жрёт 100% CPU, потому что вечно крутится в каком-нибудь безумном цикле.

И самое весёлое — это отладка. Представляешь, сидишь, ловишь гонки данных, deadlock-и в своей же асинхронщине. Волнение ебать! Иногда смотришь в логи и такой: «Сам от себя охуел». Как так вышло? Почему пакет пришёл битый? Почему клиент отключился, не дождавшись ответа? Ёперный театр!

Но когда всё-таки собирается эта махина и начинает работать стабильно, обрабатывая кучу запросов без лишних потоков — это, блядь, чистое искусство. Чувствуешь себя повелителем сетей, хотя прекрасно понимаешь, что под капотом — сплошная магия, гвозди и изолента.