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

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

25.06.2013, 01:05. Показов 5546. Ответов 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
3406 / 2177 / 354
Регистрация: 13.01.2012
Сообщений: 8,444
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
3406 / 2177 / 354
Регистрация: 13.01.2012
Сообщений: 8,444
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
3406 / 2177 / 354
Регистрация: 13.01.2012
Сообщений: 8,444
16.07.2013, 09:06
Цитата Сообщение от lavrik0000 Посмотреть сообщение
как склеить?
пардон не увидел что там UDP. на UDP нарезка не идет, надо код смотреть, позже напишу
0
0 / 0 / 0
Регистрация: 03.05.2013
Сообщений: 12
23.07.2013, 05:57  [ТС]
народ хелп уже голова болит от этой задачи(((
0
Модератор
 Аватар для vxg
3406 / 2177 / 354
Регистрация: 13.01.2012
Сообщений: 8,444
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
3406 / 2177 / 354
Регистрация: 13.01.2012
Сообщений: 8,444
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
3406 / 2177 / 354
Регистрация: 13.01.2012
Сообщений: 8,444
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
3406 / 2177 / 354
Регистрация: 13.01.2012
Сообщений: 8,444
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
3406 / 2177 / 354
Регистрация: 13.01.2012
Сообщений: 8,444
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
3406 / 2177 / 354
Регистрация: 13.01.2012
Сообщений: 8,444
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
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка. Рецензия / Мнение/ Перевод Сайт называется reddit: The Thinkpad X220 Tablet is the best budget school laptop period. Это. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru