Форум программистов, компьютерный форум, киберфорум
C++: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/25: Рейтинг темы: голосов - 25, средняя оценка - 4.80
0 / 0 / 0
Регистрация: 03.05.2013
Сообщений: 12

Как считать данные от сервера UDP

25.06.2013, 01:05. Показов 5571. Ответов 19
Метки нет (Все метки)

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

Пытаюсь на писать не большой скриптик который должен опрашивать сервера (Goldsource, Source Server). На php написал без труда правда давненько и что та уже подзабыл но не суть.
Нашел в инете инфу про сокеты на unix. Сделал по ману клиент-сервер все отработало прекрасно, сел переделывать скрипт под свои нужды. Скрипт вроде нормально отправляет данные (UDP не проконтролировать) но вот как прочитать данные полученные в ответ до меня не допирает.

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
#include <cstdlib>
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
 
using namespace std;
 
int main()
{
    string message[] = "\xFF\xFF\xFF\xFF\x54\x53\x6F\x75\x72\x63\x65\x20\x45\x6E\x67\x69\x6E\x65\x20\x51\x75\x65\x72\x79\x00";
    
    char buf[sizeof(message)];
    
    int sock;
    //Обьевбляем структуру(класс)
    struct sockaddr_in addr;
    struct in_addr iaddr;
    
    //Создаем сокет
    sock = socket(AF_INET, SOCK_DGRAM, 0);
    
    //проверяем сокет 0=TRUE / -1=False
    if(sock < 0)
    {
        perror("socket");
        exit(1);
    }
    
    addr.sin_family = AF_INET;
    addr.sin_port = htons(27015);
    addr.sin_addr.s_addr = inet_addr("77.220.182.182");
    
    int result;
    result = connect(sock, (struct sockaddr *)&addr, sizeof(addr));
    
    if(result < 0)
    {
        perror("connect");
        exit(2);
    }
    else
    {
        cout << "Работает" << endl;
    }
    system("pause");
    
    cout << send(sock, message, sizeof(message), 0) << endl;
    cout << recv(sock, buf, sizeof(message), 0) << endl; 
    
    return 0;
}
если изменить порт на котором нету сервера то функция recv возрощает -1, а если порт рабочей то прога тупа бездействует и в консоле не чего не происходит. Подскажите как получить данные плиз. В C++ знаю только базовые вещи.
Заранее премного благодарен.

Добавлено через 3 часа 1 минуту
все сделал просто я не внимательный персонаж)))
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
25.06.2013, 01:05
Ответы с готовыми решениями:

Считать данные с сервера
Есть IP, необходимо прочитать данные с сервера и вывести их. на сервере несколько строк, это значения. помогите. пожалуйста.... ...

Как отправить сообщение от сервера клиенту по UDP?
Отправляю сообщения от клиента к серверу, но не могу понять как отправить от сервера клиенту обратно. Что нужно добавить в программу? ...

Как послать UDP сообщение с сервера на определённый адрес?
у меня не получается разослать сообщение по 4м IP struct sockaddr_in socket1,socket2,socket3,socket4; socket1.sin_addr.s_addr =...

19
6 / 6 / 3
Регистрация: 30.08.2011
Сообщений: 32
27.06.2013, 20:57
Лучше используй sendto() и recvfrom(). После socket() и заполнения структуры addr необходимо произвести "связывание" сокета и адреса функцией bind(). Это будет твой сокет, с которого ты будешь отправлять запрос серверу. Затем нужно либо задать необходимые адрес и порт либо просто "замемсетить" структуру sockaddr нулями, что автоматически поставит ее в положение ANY_ADDR, т.е. будешь слушать с любого порта любого айпишника. Затем тебе нужно прочитать ман по select() http://www.opennet.ru/cgi-bin/... category=2, а там и новые вопросы появятся.

Добавлено через 23 часа 50 минут
Кстати, тут описан способ подключения к серверу по TCP-соединению. Для UDP коннект не нужен. Чтобы смотреть куда уходят пакеты на самом деле воспользуйся tcpdump.
0
0 / 0 / 0
Регистрация: 03.05.2013
Сообщений: 12
15.07.2013, 04:49  [ТС]
Цитата Сообщение от Ланселот Посмотреть сообщение
Лучше используй sendto() и recvfrom(). После socket() и заполнения структуры addr необходимо произвести "связывание" сокета и адреса функцией bind(). Это будет твой сокет, с которого ты будешь отправлять запрос серверу. Затем нужно либо задать необходимые адрес и порт либо просто "замемсетить" структуру sockaddr нулями, что автоматически поставит ее в положение ANY_ADDR, т.е. будешь слушать с любого порта любого айпишника. Затем тебе нужно прочитать ман по select() http://www.opennet.ru/cgi-bin/... category=2, а там и новые вопросы появятся.

Добавлено через 23 часа 50 минут
Кстати, тут описан способ подключения к серверу по TCP-соединению. Для UDP коннект не нужен. Чтобы смотреть куда уходят пакеты на самом деле воспользуйся tcpdump.
програ как бы заработала, вот только в ответ приходить меньше символов, приходит 20 а аналогичный скрипт на php получает 118, я так понял эту проблему можно решить с помощью функций sendto() и recvfrom(), а точней именно recvfrom???
0
Модератор
 Аватар для vxg
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,450
15.07.2013, 10:04
Цитата Сообщение от lavrik0000 Посмотреть сообщение
приходит 20
может потому что вы буфер такого размера даете функции? как она вам больше считает?
0
0 / 0 / 0
Регистрация: 03.05.2013
Сообщений: 12
15.07.2013, 10:07  [ТС]
буду дома скину рабочий код, а размер буфа делаю так char buf[4096];
0
Модератор
 Аватар для vxg
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,450
15.07.2013, 11:14
Цитата Сообщение от lavrik0000 Посмотреть сообщение
размер буфа делаю так char buf[4096]
тогда может быть нарезает пакет кусками по дороге. склеивать надо
0
0 / 0 / 0
Регистрация: 03.05.2013
Сообщений: 12
15.07.2013, 22:05  [ТС]
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
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
 
//Константы
#define IP_SOURCE "85.114.140.30"
#define IP_GOLDSOURCE "193.104.68.40"
 
#define S2A_INFO 0x49
#define A2S_INFO "\xFF\xFF\xFF\xFF\x54Source Engine Query"
#define A2S_INFO_LENGTH 25
 
using namespace std;
 
char rs_buffer[65535];
 
int main()
{
    //char* rs_buffer;
    int max_rs_size = 65535;
    
    //Иницилизируем класс
    struct sockaddr_in addr;
    
    //Создаем сокет
    int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 
    //проверяем создан ли сокет
    if(sock < 0)
    {
        perror("socket");
        exit(1);
    }
 
    //Передаем членам класса данные
    addr.sin_family = AF_INET;
    addr.sin_port = htons(27015); // или любой другой порт...
    addr.sin_addr.s_addr = inet_addr(IP_GOLDSOURCE);    
 
    //Устанавливаем соединение
    if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
    {
        perror("connect");
        exit(2);
    }
 
    send(sock, A2S_INFO, A2S_INFO_LENGTH, 0); //Отпровляем запрос на сервер
    recv(sock, rs_buffer, max_rs_size, 0); //Читаем данные от сервера  
    cout << (unsigned)strlen(rs_buffer) << endl;
    
    return 0;
    
}
вот этот код присылает сего лишь 20 символов, но я точно знаю что иъ там 118

Добавлено через 2 минуты
Цитата Сообщение от vxg Посмотреть сообщение
тогда может быть нарезает пакет кусками по дороге. склеивать надо
наверно наиглупейший вопрос, как склеить? функцией recvfrom() ?
0
Модератор
 Аватар для vxg
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,450
16.07.2013, 09:06
Цитата Сообщение от lavrik0000 Посмотреть сообщение
как склеить?
пардон не увидел что там UDP. на UDP нарезка не идет, надо код смотреть, позже напишу
0
0 / 0 / 0
Регистрация: 03.05.2013
Сообщений: 12
23.07.2013, 05:57  [ТС]
народ хелп уже голова болит от этой задачи(((
0
Модератор
 Аватар для vxg
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,450
23.07.2013, 07:43
Цитата Сообщение от lavrik0000 Посмотреть сообщение
народ хелп
вы не анализируете результат функции recv и поэтому не можете знать сколько реально она возвращает. вы можете только быть уверенными что 20-й символ нулевой
0
0 / 0 / 0
Регистрация: 03.05.2013
Сообщений: 12
23.07.2013, 08:06  [ТС]
Цитата Сообщение от vxg Посмотреть сообщение
вы не анализируете результат функции recv и поэтому не можете знать сколько реально она возвращает. вы можете только быть уверенными что 20-й символ нулевой
теперь совсем запутался))
подскажите пожалуйста, что именно мне нужно сделать?
0
Модератор
 Аватар для vxg
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,450
23.07.2013, 10:05
recv(sock, rs_buffer, max_rs_size, 0) - результат выполнения этой функции - количество принятых байтов
strlen(rs_buffer) - результат выполнения этой функции - количество байтов от начала до первого нулевого байта
таким образом если мы приняли 118 байт такого вида
01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 11 12 13 14 00 16 17 ... (всего 118 штук)
то strlen вернет нам число 20 потому как 00 у нас 21-й по счету
0
0 / 0 / 0
Регистрация: 03.05.2013
Сообщений: 12
27.07.2013, 03:56  [ТС]
Цитата Сообщение от vxg Посмотреть сообщение
recv(sock, rs_buffer, max_rs_size, 0) - результат выполнения этой функции - количество принятых байтов
strlen(rs_buffer) - результат выполнения этой функции - количество байтов от начала до первого нулевого байта
таким образом если мы приняли 118 байт такого вида
01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 11 12 13 14 00 16 17 ... (всего 118 штук)
то strlen вернет нам число 20 потому как 00 у нас 21-й по счету
и как быть что бы дальше нулевого байта прочитать?
0
Модератор
 Аватар для vxg
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,450
27.07.2013, 06:50
Цитата Сообщение от lavrik0000 Посмотреть сообщение
и как быть что бы дальше нулевого байта прочитать?
возьмите и прочитайте. у вас есть эти данные (во всяком случае если recv возвращает 118) - делайте с ними то что требуется в задаче.
0
0 / 0 / 0
Регистрация: 03.05.2013
Сообщений: 12
27.07.2013, 17:00  [ТС]
Цитата Сообщение от vxg Посмотреть сообщение
возьмите и прочитайте. у вас есть эти данные (во всяком случае если recv возвращает 118) - делайте с ними то что требуется в задаче.
пытался сделать в цикле получение данных и просто через цикл получить данные от rs_buffer серовно дальше нулевого не идет
а вот так вообще зависает цикл while(recv)
как я понял rs_buffer тупо возвращает данные до нулевого байта
0
Модератор
 Аватар для vxg
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,450
27.07.2013, 19:01
Цитата Сообщение от lavrik0000 Посмотреть сообщение
пытался сделать в цикле получение данных и просто через цикл получить данные от rs_buffer серовно дальше нулевого не идет
а вот так вообще зависает цикл while(recv)
как я понял rs_buffer тупо возвращает данные до нулевого байта
напишите
C++
1
int len = recv( бла бла бла);
и посмотрите что у вас находится в len после вызова. там должно быть 118 - берите и делайте с этими данными все что угодно. однако, помните, что если там не текст выводить содержимое буфера на экран бессмысленно.
0
0 / 0 / 0
Регистрация: 03.05.2013
Сообщений: 12
27.07.2013, 19:09  [ТС]
Цитата Сообщение от vxg Посмотреть сообщение
en = recv( бла бла бла);
если вывожу на экран консоли buf(rs_buffer) то на экране меньше символов отображается чем пришло, сделал так
C++
1
2
3
4
5
6
7
8
    static int bytes_received;
    bytes_received = recv(sock, buf, max_rs_size, 0); 
 
    string buffer;
 
    for(int i = 0; i < bytes_received; i++){
        buffer += buf[i];
    }
0
Модератор
 Аватар для vxg
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,450
27.07.2013, 20:47
если отображается символов меньше чем bytes_received то очевидно что пакет содержит строку завершающуюся нулевым символом и еще что-то. как вариант - другие идущие подряд строки так же завершающиеся нулевыми символами. я не знаю что у вас в пакете. может там вообще двоичные данные а не строки
0
0 / 0 / 0
Регистрация: 03.05.2013
Сообщений: 12
28.07.2013, 00:48  [ТС]
Цитата Сообщение от vxg Посмотреть сообщение
если отображается символов меньше чем bytes_received то очевидно что пакет содержит строку завершающуюся нулевым символом и еще что-то. как вариант - другие идущие подряд строки так же завершающиеся нулевыми символами. я не знаю что у вас в пакете. может там вообще двоичные данные а не строки
ну насколько я понял там и есть двоичные данные
тет можно глянуть как отвечает сервер
0
Модератор
 Аватар для vxg
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,450
28.07.2013, 06:56
Цитата Сообщение от lavrik0000 Посмотреть сообщение
ну насколько я понял там и есть двоичные данные
если это так то какого лешего вы их на экран выводите будто бы массив - это строка а потом удивляетесь что у вас как то там не так вывелось? странно что у вас вообще программа не падает с ошибкой доступа (спасибо надо сказать тем кто разместил в пакете в качестве одного из полей действительно строку завершающуюся нулевым символом)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
28.07.2013, 06:56
Помогаю со студенческими работами здесь

Как через UDP сокет соединить трёх клиентов без сервера?
Люди подскажите как через UDP сокет соединить трёх клиентов без сервера

Как передать данные по UDP обратно клиенту?
В Википедии нашел код: #include &lt;stdio.h&gt; #include &lt;errno.h&gt; #include &lt;string.h&gt; #include &lt;sys/socket.h&gt; #include...

Как считать статистику сервера
Добрый день уважаемые знатоки. Я делаю свой проект для игроков в GTA:SA:MP. Я его почти закончил, и у меня возникли небольшие трудности.....

как считать ответ от сервера???
Вот есть примерчик который отправляет соккет на определённый сервер на 80 порт, ну сервер по идее должен ответить, как теперь считать ответ...

Как извлечь данные из сервера Parse, чтобы эти данные были видны всем?
У меня есть активити, где есть строка, куда вводишь данные и они отправляются на сервер, и они сохраняются именно в этом активити и их вижу...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru