Форум программистов, компьютерный форум, киберфорум
C++: Сети
Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Получить внешний ip, socket,recv( ), win https://www.cyberforum.ru/ cpp-networks/ thread2694585.html
вопрос очень простой, почему данный код, прекрасно работающий на win7, не работает на win10 (не определяет ip) string GetExternalIP( ) { string ip; // Create socket object SOCKET sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); if( sock == SOCKET_ERROR ) // bad socket? { return string( );
Передача строки серверу и возврат клиенту C++
В переданной клиентом серверу строке каждый четвёртый символ нужно заменить на "%". Не могу вернуть строку с сервера. Сервер: #define _CRT_SECURE_NO_WARNINGS #include <winsock2.h> #pragma comment(lib,"Wsock32.lib") int main() { WORD wVersionRequested;
C++ Подскажите способ передачи данных через сеть https://www.cyberforum.ru/ cpp-networks/ thread2693277.html
В общем есть программа, она должна раз в сутки высылать немного текста с компьютера на другой компьютер. Проблема в том, что оба компьютера за NAT, а VDS ради такой мелочи брать не хочется, подскажите может есть в сети какой-то сервис который позволяет бесплатно обмениваться сообщениями или типа того, главное чтобы оба компьютера имели доступ к нему. Я уже думал через какой-нибудь облачный сервис...
C++ Ресурсы по сетевому программированию Здравствуйте. Посоветуйте пожалуйста какие нибудь книги или сайты или онлайн курсы видео для изучения сетевого программирования с нуля именно на с++. Заранее спасибо за ответ :) https://www.cyberforum.ru/ cpp-networks/ thread2691692.html
C++ Компиляция libcurl с openssl
Доброго времени суток! Сегодня я захотел попробовать libcurl, скачал, скомпилировал, написал небольшой тестовый проект #include <iostream> #include <curl/curl.h> #pragma comment(lib, "libcurl-d_imp.lib") int main() { CURL* curl = curl_easy_init(); if (curl) { curl_easy_setopt(curl, CURLOPT_URL, "http://www.cyberforum.ru");
C++ Проблема с конвертацией char в int Здравствуйте. У меня есть функция, которая расшифровывает ip заголовок: std::string IPv4AddrFromBytes(const char addr_bytes) { std::string addr{}; for(int i{0}; i<4; i++) //addr += std::to_string(static_cast<int>(addr_bytes)) + "."; не работает addr += std::to_string(static_cast<int>(static_cast<std::bitset<8>>(addr_bytes).to_ulong())) + "."; // работает addr =... https://www.cyberforum.ru/ cpp-networks/ thread2690954.html
C++ Как получить трассировку стека вызовов gdb? https://www.cyberforum.ru/ cpp-networks/ thread2690861.html
У меня есть дамп ядра и файл, в котором хранится отладочная информация. Могу ли я использовать gdb без использования исполняемого файла, чтобы получить стек вызовов с именем функций и строк?
C++ Отправка сообщения всем подключенным к серверу клиентам
Прошу помощи! Друзья, сервера это не моя основная специализация, данный код потребуется мне скорее всего один раз в жизни, очень прошу дать не общий совет или ссылку где посмотреть, а привести работающий пример кода =) Задача. Отправлять ВСЕМ подключенным к серверу клиентам сообщение БЕЗ запроса от клиента. Не обмен GET - SEND, а на усмотрение сервера в нужный момент отправлять всем...
C++ Как вкатиться в boost beast? Дока выглядит обрывочно. Я не могу в голове представить структуру сервера. Может есть книги по сетям на уровне абстракций буста? https://www.cyberforum.ru/ cpp-networks/ thread2690120.html C++ Не удается передать размер файла на сервер Пишу простой сервер + клиент для передачи файлов от клиента к серверу. Передача имени файла на сервер проходит без проблем. Получение размера файла у клиента и отправка на сервер происходит следующим образом: string filename; char len; .... ifstream file(filename, ios::binary | ios::ate); int lenght = file.tellg(); sprintf(len, "%d", lenght); send(my_sock, len, sizeof(len), 0); https://www.cyberforum.ru/ cpp-networks/ thread2689562.html
C++ tcp сервер, формирование очереди для пакетов
Добрый день! Используя библиотеку "WS2tcpip.h", написал простую реализацию tcp сервера. Проблема заключается в обработке данных приходящих от клиента, если клиент делает быструю отправку нескольких пакетов один за другим, то сервер считывает их как один. Подскажите пожалуйста как сформировать очередь и считывать их последовательно или как в таких случаях правильно поступать ? Ниже привожу код...
C++ Работа с FTP сервером на С++ Добрый день уважаемые форучане !!! Прошу помощи у гуру !!! сильно не принайте с++ только узнаю. Можете пожалуйста скинуть код как можно Авторизоваться на ftp сервере, скачать файл с ftp сервера, удалить файл с ftp сервера, закачать файл на ftp сервер. ??? Заранее огромное спасибо !!! :senor: https://www.cyberforum.ru/ cpp-networks/ thread2687102.html
8 / 3 / 1
Регистрация: 11.08.2016
Сообщений: 44
0

Winsock и цикл сообщений - C++ - Ответ 14823324

07.09.2020, 02:19. Показов 3175. Ответов 6
Метки (Все метки)

Author24 — интернет-сервис помощи студентам
В общем, делаю лабу универскую, пытаюсь разобраться с Winsock, но никак не могу понять, в чем проблема. Сначала скину код.
Сервер:
Кликните здесь для просмотра всего текста

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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#define _WINSOCK_DEPRECATED_NO_WARNINGS
 
#include "Winsock2.h"                // заголовок  WS2_32.dll
#pragma comment(lib, "WS2_32.lib")   // экспорт  WS2_32.dll
 
#include <iostream>
#include <string>
 
std::string SetErrorMsgText(std::string msgText, int code);
std::string itos(int i);
 
union Converter // для перевода int в char[4] и обратно
{
    int number;
    char bytes[4];
};
 
int main()
{
    WSADATA wsaData;
    try
    {
        // инициализация библиотеки
        if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
            throw SetErrorMsgText("Startup:", WSAGetLastError());
 
        // создаем СОКЕТ ДЛЯ ПРОСЛУШИВАНИЯ ПОРТА и получаем его дескриптор
        SOCKET serverSocket = socket(
            AF_INET,        //[in]  формат адреса: TCP/IP - AF_INET, не должен быть = null!!!
            SOCK_STREAM,    //[in]  тип сокета: ориентированный на сообщения (UDP, SOCK_DGRAM) или на поток (TCP, SOCK_STREAM)
            IPPROTO_TCP     //[in]  протокол транспортного уровня. для tcp можно указать null
        );
        if (serverSocket == INVALID_SOCKET)
            throw SetErrorMsgText("socket:", WSAGetLastError());
 
        SOCKADDR_IN serv;                     // параметры  сокета sS
        serv.sin_family = AF_INET;            // используется IP-адресация  
        serv.sin_port = htons(2000);          // порт 2000
        serv.sin_addr.s_addr = INADDR_ANY;    // ответ присылать на IP-адрес: любой собственный IP-адрес 
 
        if (bind(serverSocket, (LPSOCKADDR)&serv, sizeof(serv)) == SOCKET_ERROR)
            throw SetErrorMsgText("bind:", WSAGetLastError());
        // запуск прослушивания сокетом порта
        if (listen(serverSocket, SOMAXCONN) == SOCKET_ERROR) // SOMAXCONN - максимально возможная длина очереди подключений
            throw SetErrorMsgText("socket can't listen to port: ", WSAGetLastError());
        // теперь клиентская прог может вызывать connect() для подключения
 
        // переменные для работы с клиентом
        SOCKADDR_IN clientSocketInfo;       // параметры сокета клиента
        int size = sizeof(SOCKADDR_IN);     // размер структуры этих параметров
        SOCKET clientSocket;                // СОКЕТ ДЛЯ ОБМЕНА ДАННЫМИ
 
        memset(&clientSocketInfo, 0, sizeof(clientSocketInfo)); // обнулить память
        
 
        std::cout << "Server is listening to port 2000...\n";
        // получаем дескриптор сокета для обмена данными по КАНАЛУ
        clientSocket = accept(serverSocket,                 // [in]  дескриптор связанного сокета
                            (sockaddr*)&clientSocketInfo,   // [out] указатель на sockaddr
                            &size);             // [out] указатель на длину структуры sockaddr
 
        if (clientSocket == INVALID_SOCKET)
            throw SetErrorMsgText("socket: ", WSAGetLastError());
 
        // служебная инфа
        std::cout << "IP address: " << inet_ntoa(clientSocketInfo.sin_addr) << std::endl << "Port: " << htons(clientSocketInfo.sin_port) << std::endl;
 
        Converter dataSize;
        char* buffer;
 
        for(int i = 0; i < 1000; i++) {
            // принимаем размер будущих данных
            char* cSize = new char[4]; // 4 байта = int
            memset(cSize, 0, 4);
            int byteCounter = 0;
            byteCounter = recv(clientSocket, cSize, sizeof(int), NULL); // 4-й аргумент: NULL - после получения входной буфер очищается, MSG_PEEK - входной буфер не очищается
            //byteCounter = recv(clientSocket, cSize, sizeof(int), NULL); // 4-й аргумент: NULL - после получения входной буфер очищается, MSG_PEEK - входной буфер не очищается
            if (byteCounter == SOCKET_ERROR)
                throw SetErrorMsgText("recv: ", WSAGetLastError());
            std::cout << "MESSAGE SIZE = " << byteCounter << std::endl;
            
            // конвертируем
            dataSize.bytes[0] = cSize[0];
            dataSize.bytes[1] = cSize[1];
            dataSize.bytes[2] = cSize[2];
            dataSize.bytes[3] = cSize[3];
 
 
            buffer = new char[dataSize.number];
            memset(buffer, 0, dataSize.number);
            std::cout << "Getting " << dataSize.number << " bytes...\n";
 
            byteCounter = 0;
            while (byteCounter < dataSize.number)
            {
                byteCounter += recv(clientSocket, buffer, dataSize.number, MSG_PEEK); // 4-й аргумент: NULL - после получения входной буфер очищается, MSG_PEEK - входной буфер не очищается
                if (byteCounter == SOCKET_ERROR)
                    throw SetErrorMsgText("recv: ", WSAGetLastError());
            }
            std::cout << buffer << std::endl << "Bytes got: " << byteCounter << std::endl;
            delete[] buffer;
            delete[] cSize;
        }
 
        // закрываем сокеты
        if (closesocket(clientSocket) == SOCKET_ERROR)
            throw SetErrorMsgText("closing client socket error:", WSAGetLastError());
        if (closesocket(serverSocket) == SOCKET_ERROR)
            throw SetErrorMsgText("closing server socket error:", WSAGetLastError());
 
        // выгрузка библиотеки
        if (WSACleanup() == SOCKET_ERROR)
            throw SetErrorMsgText("Cleanup:", WSAGetLastError());
    }
    catch (std::string errorMsgText)
    {
        std::cout << std::endl << std::endl << errorMsgText;
        getchar();
    }
    std::cout << "DONE.";
    getchar();
    return 0;
}
 
std::string GetErrorMsgText(int code)    // cформировать текст ошибки 
{
    std::string msgText;
    switch (code)                      // проверка кода возврата  
    {
    case WSAEINTR: msgText = "WSAEINTR"; break;
    case WSAEACCES: msgText = "WSAEACCES"; break;
    case WSAEFAULT: msgText = "WSAEFAULT"; break;
    case WSAEINVAL: msgText = "WSAEINVAL"; break;
        //..........коды WSAGetLastError ..........................
    case WSASYSCALLFAILURE: msgText = "WSASYSCALLFAILURE"; break;
    default: msgText = "UNKNOWN ERROR. CODE: " + itos(code); break;
    };
    return msgText;
};
 
std::string SetErrorMsgText(std::string msgText, int code) { return  msgText + GetErrorMsgText(code); };
 
#include <sstream>
std::string itos(int i) // convert int to string
{
    std::stringstream s;
    s << i;
    return s.str();
}

Клиент:
Кликните здесь для просмотра всего текста

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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
 
#include "Winsock2.h"                // заголовок  WS2_32.dll
#pragma comment(lib, "WS2_32.lib")   // экспорт  WS2_32.dll
 
#include <iostream>
#include <string>
 
std::string SetErrorMsgText(std::string msgText, int code);
// Преобразование int в string
std::string itos(int i);
 
 
union Converter // для перевода int в char[4] и обратно
{
    int number;
    char bytes[4];
};
 
int main()
{
    WSADATA wsaData;
    try
    {
        // инициализация библиотеки
        if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
            throw SetErrorMsgText("Startup:", WSAGetLastError());
 
        // создаем СОКЕТ ДЛЯ ОТПРАВЛЕНИЯ и получаем его дескриптор
        SOCKET clientSocket = socket(
            AF_INET,        //[in] формат адреса: TCP/IP - AF_INET, не должен быть = null!!!
            SOCK_STREAM,    //[in] тип сокета: ориентированный на сообщения (UDP, SOCK_DGRAM) или на поток (TCP, SOCK_STREAM)
            IPPROTO_TCP     //[in] протокол транспортного уровня. для tcp можно указать null
        );
        if (clientSocket == INVALID_SOCKET)
            throw SetErrorMsgText("socket:", WSAGetLastError());
 
        SOCKADDR_IN serverInfo; // параметры сокета сервера
        memset(&serverInfo, 0, sizeof(serverInfo)); // обнулить память
        serverInfo.sin_family = AF_INET;                        // тип сети
        serverInfo.sin_port = htons(2000);                      // порт для подключения
        serverInfo.sin_addr.s_addr = inet_addr("127.0.0.1");    // IP-адрес сервера для подключения
        //serverInfo.sin_addr.s_addr = inet_addr("192.168.56.103"); // IP-адрес сервера для подключения
 
        std::cout << "Connecting...\n";
        if (connect(clientSocket, (LPSOCKADDR)&serverInfo, sizeof(serverInfo)) == SOCKET_ERROR)
            throw SetErrorMsgText("can't connect: ", WSAGetLastError());
 
        for (int i = 0; i < 1000; i++)
        {
            std::string message = "Hello from Client " + itos(i);
            
            const char* m = message.c_str();
 
            std::cout << m << std::endl;
 
            Converter size;
            size.number = strlen(m);
 
            // отправляем размер
            std::cout << "Sending " << size.number << " bytes...\n";
 
            int code = send(clientSocket, size.bytes, sizeof(int), NULL);
            if (code == SOCKET_ERROR)
                throw SetErrorMsgText("send: ", WSAGetLastError());
 
            // теперь отправляем сами данные
            code = send(clientSocket, m, size.number, NULL);
            if (code == SOCKET_ERROR)
                throw SetErrorMsgText("send: ", WSAGetLastError());
            
            getchar();
        }
 
        // закрываем сокеты
        if (closesocket(clientSocket) == SOCKET_ERROR)
            throw SetErrorMsgText("closesocket:", WSAGetLastError());
 
        // выгрузка библиотеки
        if (WSACleanup() == SOCKET_ERROR)
            throw SetErrorMsgText("Cleanup:", WSAGetLastError());
    }
    catch (std::string errorMsgText)
    {
        std::cout << std::endl << std::endl << errorMsgText;
    }
    std::cout << "\n\nDONE.";
    getchar();
    return 0;
}
 
std::string GetErrorMsgText(int code)    // cформировать текст ошибки 
{
    std::string msgText;
    switch (code)                      // проверка кода возврата  
    {
    case WSAEINTR: msgText = "WSAEINTR"; break;
    case WSAEACCES: msgText = "WSAEACCES"; break;
    case WSAEFAULT: msgText = "WSAEFAULT"; break;
    case WSAEINVAL: msgText = "WSAEINVAL"; break;
        //..........коды WSAGetLastError ..........................
    case WSASYSCALLFAILURE: msgText = "WSASYSCALLFAILURE"; break;
    default: msgText = "UNKNOWN ERROR. CODE: " + itos(code); break;
    };
    return msgText;
};
 
std::string SetErrorMsgText(std::string msgText, int code) { return  msgText + GetErrorMsgText(code); };
 
#include <sstream>
std::string itos(int i) // convert int to string
{
    std::stringstream s;
    s << i;
    return s.str();
}

Какую дичь я только не пробовал (думаю, по коду вы это понимаете), все равно не работает.
Задание такое: отправить 1000 раз сообщение "Hello from Client XXX", где XXX - номер сообщения.
Т.к. сообщение у меня переменной длины, то сначала я отправляю его размер, а затем само сообщение. Вроде бы адекватное решение, верно? На сервере соответственно я сначала читаю размер будущего сообщения, затем само смс. Но почему-то на сервере во время 2-й итерации происходит вылет при инициализации массива buffer: size.number принимает аномально огромное значение. Глянув внимательно в консоль сервера и прогнав через отладчик, я понял, что при 1-й итерации массив имеет размер 19 символов (тут все верно), но в консоль каждый раз выводит одни и те же 23 (wtf?) символа: "Hello from Clientээээ". Что за бред? Первая глупость, приходящая в голову: 4-хбайтовый размер следующего СМС прилетел сюда, из-за чего появились эти символы и на 2-й итерации в size.number записываются уже другие 4 байта. Но т.к. клиент останавливается с помощью getchar(), это просто невозможно! Также заметил, что на 2-й итерации в массив cSize, что в начале цикла, постоянно записывается значение "Hellээээ*~Ъ\". Часть от отправленной фразы длиной в 4 байта?.. В общем, я окончательно запутался в этом вопросе. Я гуглил эту тему, но ответа так и не нашел. Плохо гуглил? Пожалуйста, объясните начинающему студенту, как правильно отправлять такие сообщения и исправить ошибки.
Заранее спасибо! Удачи всем и хорошего кода!

Вернуться к обсуждению:
Winsock и цикл сообщений C++
0
Лучшие ответы (1)
Заказать работу у эксперта
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.09.2020, 02:19
Готовые ответы и решения:

Цикл сообщений и функция их обработки
вечер добрый! я почти нулевой новичок в win api, в одном из первых примеров, которые я смотрел...

Чем отличается цикл сообщений в скрытом окне от бесконечного цикла?
Написал прогу под WinAPI, которая перебирает все окна в бесконечном цикле #include &lt;windows.h&gt;...

Отправка сообщений. Winsock, send и telnet
Приветствую. Пишу простенький сервер. Использую Delphi 6, winsock. Клиентом является стандартный...

Цикл обработки сообщений
Можно ли как то отобразить основной цикл обработки сообщений в WinForms c++ если нет то как...

6
07.09.2020, 02:19
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.09.2020, 02:19
Помогаю со студенческими работами здесь

Как реализовать цикл ввода сообщений?
Программа должна выпольняться пока пользователь не введет слово Exit. Программа спрашивает...

Может так случится, что процесс приема новых сообщений и их прорисовки превратится в бесконечный цикл?
Допустим у меня есть приложение, которое добавляет в себя поступающие сообщения. А эти сообщения...

Используйте цикл for для вывода сообщений об именах и id десяти тегов <span> при нажатии кнопки.
Помогите пожалуйста. Используйте цикл for для вывода сообщений об именах и id деся-ти тегов...

Создать программу по всем 3 видам циклов...цикл с параметром,цикл с условием,цикл,и цикл с предусловием...
Найти сумму чисел 1 в квадрате до 10 c квадрате...операцию возведению в степень не использовать...

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

Вычислить и вывести сумму чётных целых чисел в интервале от 1 до n: 1) цикл «ДО» 2) цикл «ПОКА» 3) цикл «ДЛЯ»
Вычислить и вывести сумму чётных целых чисел в интервале от 1 до n: 1. цикл «ДО» 2. цикл «ПОКА»...

0
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru