С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
 Аватар для Dinkin
783 / 556 / 136
Регистрация: 31.05.2013
Сообщений: 3,145
Записей в блоге: 3

winsock2.h и recv

03.09.2024, 15:35. Показов 1437. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день!

Есть простое сокетное соединение к серверу. Сервер беспрерывно шлет пакеты. Ну что бы чтения избежать потерю данных, сервер предварительно шлет 4 байта это длину пакета, а потом сам пакет, и как бы организовать такое чтение?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
    WSADATA WsaData;
    WORD WordDllVersion = MAKEWORD(2, 1);
 
    int startUp = WSAStartup (WordDllVersion, &WsaData);
 
    if(startUp != 0)
        return 1;    
 
    // Создаем сокет
    client_socket = socket(AF_INET, SOCK_STREAM, 0);
 
    if(client_socket < 0)  
        return 2;
 
    // Создаем подключение и пробуем подключится  (что что адрес ниже, он является как по умолчанию для системы Сергея)
    sockaddr_in socket_addr_connect;
    socket_addr_connect.sin_family      = AF_INET;
    socket_addr_connect.sin_addr.s_addr = inet_addr ("127.0.0.1");
    socket_addr_connect.sin_port        = htons (4545);
 
    int codeCheck = connect (client_socket, (sockaddr*)&socket_addr_connect, sizeof (socket_addr_connect));
 
    if (codeCheck != 0)
        return 3;       
 
    run_socket = true; // Включаem режим постояной прослушки, обычная глобальная bool
 
    char line_buffer[4];
    char buffer[256];
 
    while(run_socket)
        {
            // Получаем первый пакет что бы знать длину всей строки
            int res = recv(client_socket, line_buffer, 4, 0);
 
            if(res > 0)
                {
                    //  и вот тут надо 4 байта в длину покета и что ли цикл ждать, пока не прийдет пакет доконца
 
                }
        }
 
 
    closesocket (client_socket);
    WSACleanup();
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
03.09.2024, 15:35
Ответы с готовыми решениями:

Странности работы функции recv (winsock2)
Здравствуйте. Поисковик мне не помог, ничего похожего на форуме найти не удалось, поэтому - создам сам. Когда начинал писать сервер на...

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

Не компилируются WinSock2.h, winsock2.h, ws2def.h
Требуется получить инфу из базы данных MySQL на сервере. Поставил MySQL Сервер, подключил к проекту, однако не компилится из-за огромного...

13
184 / 72 / 35
Регистрация: 09.05.2022
Сообщений: 387
03.09.2024, 18:04
Лучший ответ Сообщение было отмечено Dinkin как решение

Решение

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>
#include <vector>
#include <cstdint>
 
#pragma comment(lib, "ws2_32.lib")
 
SOCKET client_socket;
bool run_socket;
 
int main() {
    WSADATA WsaData;
    WORD WordDllVersion = MAKEWORD(2, 1);
 
    int startUp = WSAStartup(WordDllVersion, &WsaData);
 
    if(startUp != 0) {
        std::cout << "WSAStartup failed." << std::endl;
        return 1;
    }
 
    // Создаем сокет
    client_socket = socket(AF_INET, SOCK_STREAM, 0);
 
    if(client_socket == INVALID_SOCKET) {
        std::cout << "Socket creation failed." << std::endl;
        WSACleanup();
        return 2;
    }
 
    // Создаем подключение и пробуем подключиться
    sockaddr_in socket_addr_connect;
    socket_addr_connect.sin_family = AF_INET;
    socket_addr_connect.sin_addr.s_addr = inet_addr("127.0.0.1");
    socket_addr_connect.sin_port = htons(4545);
 
    int codeCheck = connect(client_socket, (sockaddr*)&socket_addr_connect, sizeof(socket_addr_connect));
 
    if (codeCheck != 0) {
        std::cout << "Connection failed." << std::endl;
        closesocket(client_socket);
        WSACleanup();
        return 3;
    }
 
    run_socket = true;
 
    while(run_socket) {
        // Читаем длину пакета (4 байта)
        uint32_t packet_length = 0;
        int bytes_received = 0;
        char* length_ptr = reinterpret_cast<char*>(&packet_length);
 
        while (bytes_received < 4) {
            int res = recv(client_socket, length_ptr + bytes_received, 4 - bytes_received, 0);
            if (res <= 0) {
                std::cout << "Connection closed or error occurred." << std::endl;
                run_socket = false;
                break;
            }
            bytes_received += res;
        }
 
        if (!run_socket) break;
 
        // Конвертируем длину пакета из network byte order в host byte order
        packet_length = ntohl(packet_length);
 
        // Читаем сам пакет
        std::vector<char> buffer(packet_length);
        bytes_received = 0;
 
        while (bytes_received < packet_length) {
            int res = recv(client_socket, buffer.data() + bytes_received, packet_length - bytes_received, 0);
            if (res <= 0) {
                std::cout << "Connection closed or error occurred." << std::endl;
                run_socket = false;
                break;
            }
            bytes_received += res;
        }
 
        if (run_socket) {
            // Обработка полученного пакета
            std::cout << "Received packet of length " << packet_length << ": ";
            std::cout.write(buffer.data(), packet_length);
            std::cout << std::endl;
        }
    }
 
    closesocket(client_socket);
    WSACleanup();
    return 0;
}
1
фрилансер
 Аватар для Алексей1153
6449 / 5643 / 1129
Регистрация: 11.10.2019
Сообщений: 15,021
03.09.2024, 18:53
Dinkin, например, такой протокол:

длина пакета
пакет
CRC16

поскольку TCP трафик может приходить любыми кусками (но в правильном порядке), есть необходимость копить всё входящее в буфере и уже в накопленном пытаться разобрать разметку.
1
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,531
Записей в блоге: 1
04.09.2024, 09:30
Алексей1153, а почему бы не достаточно было 2х ресивов?
Получил длину сообщения.
Получил сообщение длиной "длина".
Разве как раз потому что у нас такой умный протокол TCP, ресив, которому сказали получить N байт, не будет терпеливо их ждать, склеивая внутри ОС и сетевого железа тот самый буфер до посинения?
1
фрилансер
 Аватар для Алексей1153
6449 / 5643 / 1129
Регистрация: 11.10.2019
Сообщений: 15,021
04.09.2024, 09:43
Kuzia domovenok, TCP обеспечивает, что байты придут в том же порядке, что были отправлены (если, конечно, провод не перерезали). Но порции, которыми будут данные приходить, в общем случае неизвестны.

Это UDP пакет целиком доставляет, но при этом доставка и порядок самих пакетов не гарантируется
1
 Аватар для Dinkin
783 / 556 / 136
Регистрация: 31.05.2013
Сообщений: 3,145
Записей в блоге: 3
04.09.2024, 11:53  [ТС]
karlhildekruger, Возможно как то переиграть эти моменты? у меня "билдоровский" компилятор, и он слегка устарел и не знает таких моментов (библиотеки подключены)
Миниатюры
winsock2.h и recv  
0
 Аватар для Dinkin
783 / 556 / 136
Регистрация: 31.05.2013
Сообщений: 3,145
Записей в блоге: 3
04.09.2024, 12:25  [ТС]
Убрал стандартный компилятор, убрал все визуальные хвосты, скомпилировалось.
Я правильно понимаю, что тут
C++
1
std::cout.write(buffer.data(), packet_length);
в buffer, это завершенный пакет?...есл да, то для чего его в вектор поместили?
0
фрилансер
 Аватар для Алексей1153
6449 / 5643 / 1129
Регистрация: 11.10.2019
Сообщений: 15,021
04.09.2024, 12:26
Dinkin,
buffer.data()
можно заменить на
&buffer[0]
1
 Аватар для Dinkin
783 / 556 / 136
Регистрация: 31.05.2013
Сообщений: 3,145
Записей в блоге: 3
04.09.2024, 22:09  [ТС]
а так что на счет вектора buffer?

Добавлено через 35 минут
Разобрался, почему вектор...
К сожалению выше пример, выходит в бесконечный цикл =(

Добавлено через 5 часов 40 минут
Спасибо, дебит с кредитом сошлись
0
05.09.2024, 18:40

Не по теме:

Алексей1153, гы-гы, можно было и не объяснять.
Проблема с получением пакетов по TCP соединению
Он через год опять об этом забудет.

0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,531
Записей в блоге: 1
06.09.2024, 15:38
ablex, а что? Разве это работает?
0
08.09.2024, 00:07

Не по теме:

Kuzia domovenok, что "это"?

0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,531
Записей в блоге: 1
09.09.2024, 13:13
tcp portokol
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
09.09.2024, 14:39
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
tcp
раз паутина доступна, значит работает
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
09.09.2024, 14:39
Помогаю со студенческими работами здесь

winSock2
Функция socket постоянно выдает INVALID_SOCKED. Необходимо создать форму клиент сервер IPX приложения с использованием WinSock2/ и передать...

winsock2.h
Компилирую обычный код: #pragma comment(lib, &quot;ws2_32&quot;) #include &lt;winsock2.h&gt; int main() { } Ошибки: 1&gt;------...

WINSOCK2 C++
День добрый. Не могли бы вы подсказать пару мест, где можно было бы просмотреть синтаксис библиотеки указанной в шапке?

winsock2
Помогите, вот код: if(WSAConnect(sock, (SOCKADDR*)&amp;addr, sizeof(addr))) { cout &lt;&lt; &quot;Connected!&quot;; ...

winsock2
вот у меня чатик вообщем есть =) может кто нибудь подсказать, как сделать чтобы он не только на 127.0.0.1 работал? типа чтото с upd надо...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru