0Pricing
C Academy · Урок

TCP-клиент

Подключайтесь и отправляйте данные

«TCP-клиент» — бесплатный урок C Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C Academy содержит 4 уроков всего.

Создание TCP-клиента

TCP-клиент подключается к серверу, а затем отправляет и получает данные. Его жизненный цикл короче, чем у сервера: создать сокет, подключиться, обменяться данными и закрыть соединение.

Шаг 1: создание сокета

Как и сервер, создайте потоковый сокет для IPv4 TCP.

#include <sys/socket.h>
#include <stdio.h>

int make_client_socket(void) {
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd < 0) perror("socket");
    return fd;
}

Шаг 2: описание сервера

Заполните sockaddr_in, указав порт и IP-адрес сервера. Используйте inet_pton, чтобы преобразовать строку IP-адреса с точками в двоичную форму.

#include <arpa/inet.h>
#include <netinet/in.h>

int set_server(struct sockaddr_in *addr, const char *ip, unsigned short port) {
    addr->sin_family = AF_INET;
    addr->sin_port = htons(port);
    return inet_pton(AF_INET, ip, &addr->sin_addr); /* 1 on success */
}

Шаг 3: подключение

connect() выполняет TCP-рукопожатие с сервером. При успехе сокет готов к обмену данными; при сбое устанавливается значение errno (например, при отказе в подключении).

#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>

int do_connect(int fd, struct sockaddr_in *addr) {
    if (connect(fd, (struct sockaddr *)addr, sizeof *addr) < 0) {
        perror("connect"); return -1;
    }
    return 0;
}

Связывать с адресом не требуется

Клиенты обычно пропускают вызов bind: во время connect ядро автоматически назначает эфемерный исходный порт. Связывайте клиентский сокет с адресом только при необходимости использовать определённый исходный порт.

Шаг 4: отправка данных

После подключения отправьте запрос с помощью send. Повторяйте вызов, чтобы убедиться, что весь буфер отправлен.

#include <sys/socket.h>
#include <string.h>

int send_all(int fd, const char *data) {
    size_t left = strlen(data);
    const char *p = data;
    while (left > 0) {
        ssize_t n = send(fd, p, left, 0);
        if (n <= 0) return -1;
        p += n; left -= (size_t)n;
    }
    return 0;
}

Шаг 5: получение ответа

Прочитайте ответ сервера с помощью recv. Перед обработкой буфера как строки добавьте нулевой завершающий символ.

#include <sys/socket.h>
#include <stdio.h>

void read_reply(int fd) {
    char buf[512];
    ssize_t n = recv(fd, buf, sizeof buf - 1, 0);
    if (n > 0) { buf[n] = 0; printf("server said: %s\n", buf); }
    else if (n == 0) printf("server closed connection\n");
}

Чтение до закрытия соединения

Один вызов recv может не вернуть весь ответ. Повторяйте вызов, пока recv не вернёт 0 (другая сторона закрыла соединение), чтобы прочитать полный ответ, поступающий частями.

#include <sys/socket.h>
#include <stdio.h>

void drain(int fd) {
    char buf[256]; ssize_t n;
    while ((n = recv(fd, buf, sizeof buf, 0)) > 0)
        fwrite(buf, 1, (size_t)n, stdout);
}

Шаг 6: закрытие

Вызовите close(fd), чтобы завершить соединение и освободить дескриптор. Это отправляет TCP-сообщение FIN, благодаря чему сервер узнаёт, что клиент закончил работу.

#include <unistd.h>

void finish(int fd) {
    close(fd);
}

Полузакрытие с помощью shutdown

shutdown(fd, SHUT_WR) закрывает только направление записи, сообщая о завершении запроса и при этом позволяя клиенту читать ответ. Это полезно для протоколов «запрос — ответ».

Обработка сбоев подключения

Распространённые ошибки клиента: ECONNREFUSED (сервер не прослушивает подключения), ETIMEDOUT (узел недоступен) и EHOSTUNREACH. Всегда проверяйте connect и ясно сообщайте пользователю о сбоях.

Быстрая проверка

Проверьте, насколько хорошо Вы понимаете работу клиентов TCP.

Повторение

Вы создали клиента TCP.

  • создайте сокет, затем подключитесь к серверу по адресу sockaddr_in
  • Вызывать bind не нужно: ядро выберет исходный порт
  • отправьте запрос и получите ответ с помощью recv (для получения всех данных используйте цикл)
  • после завершения вызовите close или shutdown; обработайте сбои подключения

Часто задаваемые вопросы

Урок «TCP-клиент» бесплатный?

Да — полный текст урока «TCP-клиент» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C Academy, подпишись на CoddyKit PRO. Курс C Academy содержит 4 уроков всего.

Чему я научусь в уроке «TCP-клиент»?

Подключайтесь и отправляйте данные Ты практикуешь C Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C Academy?

Предыдущий опыт не требуется. C Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «TCP-клиент»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C Academy?

Да. Каждый урок C Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Обзор сокетов
  2. TCP-сервер
  3. TCP-клиент
  4. Обработка нескольких клиентов
← Назад к C Academy