Модераторы: feodorv

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> sockets: в чём я ошибаюсь? recvfrom странно себя ведёт или я? 
V
    Опции темы
Apel
Дата 31.8.2006, 01:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 30.8.2006

Репутация: нет
Всего: нет



Основной код:

Код

#define RSP_RCON_NUM     "яяяяchallenge rcon"
#define RSP_SRV_DETAILS  "яяяяdetails"


Код

int CHLDSManager::Query(char *Address, u_short Port, char *QueryString)
{
  WSADATA WSAData;
  if (!WSAStartup(WINSOCK_VERSION, &WSAData))
  {
    SOCKET Socket; 
    if ((Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) != INVALID_SOCKET)
    {
      sockaddr_in to;
      to.sin_family = AF_INET;
      to.sin_port = htons(Port);
      to.sin_addr.S_un.S_addr = inet_addr(Address);
      int sended;
      if ((sended = sendto(Socket, QueryString, (int)strlen(QueryString), 0, (sockaddr *)&to, sizeof(to))) != SOCKET_ERROR)
      {
    sockaddr from;
    int recved, from_size = sizeof(from);
    if ((recved = recvfrom(Socket, Buffer, sizeof(Buffer), 0,(sockaddr *) &from, &from_size)) != SOCKET_ERROR)
    {
      WSACleanup();
      return recved;
    }
      }
    }
  }
  WSACleanup();
  return -1;
}

Код

void CHLDSManager::Refresh(void)
{
//int Query(char *Address, u_short Port, char *QueryString);
  if(CHLDSManager::Query("85.196.218.188", 27017, <qstr> ) > 0)
  {
    MessageBoxA(0, Buffer, "Buffer Content", 0);
  }
}


Когда третий параметр функции Query равен RSP_RCON_NUM, всё в порядке, функция получает ответ сервера (соответствующий запросу). Когда же третий параметр равен RSP_SRV_DETAILS, функция recvfrom "зависает". Буфер для получаемых данных заведомо большего размера. Предпологаю, что она ждёт, пока сервер ответит? Известно точно, что сервер всегда отвечает на правильные запросы. Пробовал менять серверы, результат один. И, самое интересное, этот код совсем недавно прекрасно работал. Не пойму, что я мог такого изменить, что вдруг перестало работать. Помогите разобраться.
PM MAIL   Вверх
Apel
Дата 31.8.2006, 05:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 30.8.2006

Репутация: нет
Всего: нет



Написал весь код заново. работает на одном сервере. На остальных не хочет, опять проблемы с получением данных. Может, надо как-то по-особому данные получать? Возможно такое, что, раз протокол UDP, то данные 100% теряются? Хотя, другие программы получают эти же данные без проблем. smile 
PM MAIL   Вверх
ptr
Дата 31.8.2006, 06:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 661
Регистрация: 31.5.2006
Где: Новосибирск

Репутация: 9
Всего: 14



Apel, что за сервера то?

Цитата(Apel @  31.8.2006,  09:15 Найти цитируемый пост)
Возможно такое, что, раз протокол UDP, то данные 100% теряются?

Возможно.


--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
Apel
Дата 31.8.2006, 07:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 30.8.2006

Репутация: нет
Всего: нет



Но ведь другие клиенты для данного сервера, по такому же протоколу получают данные, и для одного-единственного сервера данные получаю в полном объёме. А для других серверов не приходят данные большого объёма. Может, они застрявают в каком-нибудь буфере?
PM MAIL   Вверх
ptr
Дата 31.8.2006, 08:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 661
Регистрация: 31.5.2006
Где: Новосибирск

Репутация: 9
Всего: 14



Apel, давай по порядку.
1. Что за сервера?
2. Ты переписал программу, так новый давай код.

Цитата(Apel @  31.8.2006,  11:43 Найти цитируемый пост)
Но ведь другие клиенты для данного сервера, по такому же протоколу получают данные, и для одного-единственного сервера данные получаю в полном объёме.

UDP не даёт никаких гарантий.

Это сообщение отредактировал(а) ptr - 31.8.2006, 08:26


--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
Apel
Дата 31.8.2006, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 30.8.2006

Репутация: нет
Всего: нет



Код

int CHLDSManager::Query(char *Address, u_short Port, char *QueryString)
{
  WSADATA WSAData;
  int recved;
  if (!WSAStartup(WINSOCK_VERSION, &WSAData))
  {
    SOCKET Socket; 
    if ((Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) != INVALID_SOCKET)
    {
      sockaddr_in to;
      to.sin_family = AF_INET;
      to.sin_port = htons(Port);
      to.sin_addr.S_un.S_addr = inet_addr(Address);
      int sended;
      if ((sended = sendto(Socket, QueryString, (int)strlen(QueryString), 0, (sockaddr *)&to, sizeof(to))) != SOCKET_ERROR)
      {
    sockaddr from;
    int from_size = sizeof(from);
    if ((recved = recvfrom(Socket, Buffer, sizeof(Buffer), 0,(sockaddr *) &from, &from_size)) != SOCKET_ERROR)
    {
        if(closesocket(Socket) != SOCKET_ERROR)
      {
        if(WSACleanup())return RET_FAIL;
      }  
    }    
      }
    }
  }
  return recved;
}

вот "новый" код. Он работает. Но почему-то функция recvfrom при получении большого ответа на запрос (большого, относительно других, на которые ответы приходят правильно и сразу) не завершается. Относительно серверов - это игровые серверы Counter-Strike, данная функция предназначена для получения разной информации о сервере в соответствии с протоколом. На одном сервере этот код замечательно работает. И на разных тоже работал, но вдруг перестал. Даже на локальном сервере не приходят некоторые ответы.

То, что протокол UDP не гарантирует доставку пакетов я знаю, но ничего не поделать, если сервер желает общаться только по UDP, и то не всегда smile 

Это сообщение отредактировал(а) Apel - 31.8.2006, 12:20
PM MAIL   Вверх
sOckets
Дата 31.8.2006, 16:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


ЖгуПоПонедельникам
**


Профиль
Группа: Участник
Сообщений: 298
Регистрация: 24.8.2006
Где: ws2.lib

Репутация: нет
Всего: 2



Почему бы не отметить что вопрос решён ? =\ что так трудно это сделать ?


--------------------
Я Будущий сотрудник Google Inc. Юзаем Google Code Search для поиска исходников. Юзаем GMail как почту.
PM   Вверх
Apel
Дата 31.8.2006, 17:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 30.8.2006

Репутация: нет
Всего: нет



Цитата(ilovewinsocks @ 31.8.2006,  16:59)
Почему бы не отметить что вопрос решён ? =\ что так трудно это сделать ?

Если бы Вы внимательно читали, то поняли бы, что вопрос не решён. Код переписан заново, но не отличается практически от предыдущего, а в плане получения данных от сервера идентичен. Вопрос заключается в том, что этот код то работает, то нет. Функция recvfrom отказывается получать данные по правильному запросу от всех серверов, кроме одного выдающегося неизвестно чем. До создания класса я проводил эксперимент с простой функцией, на разных серверах, по всем запросам приходили правильные ответы. Вопрос остаётся открыт: что может мешать функции recvfrom получить данные размером менее 200 байт?
PM MAIL   Вверх
sOckets
Дата 1.9.2006, 18:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


ЖгуПоПонедельникам
**


Профиль
Группа: Участник
Сообщений: 298
Регистрация: 24.8.2006
Где: ws2.lib

Репутация: нет
Всего: 2



До этого он был решён по вашим словам. Затем появилась другая проблема.Вы же сами это видите так как это ваша тема, так зачем же просто так обижать участника форума заявив что он не внимательно читает Темы. ?


--------------------
Я Будущий сотрудник Google Inc. Юзаем Google Code Search для поиска исходников. Юзаем GMail как почту.
PM   Вверх
ptr
Дата 2.9.2006, 05:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 661
Регистрация: 31.5.2006
Где: Новосибирск

Репутация: 9
Всего: 14



Apel, а ты уверен в том, что серверы действительно посылают ответ?


--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
Apel
Дата 2.9.2006, 07:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 30.8.2006

Репутация: нет
Всего: нет



2 ilovewinsocks:
Прошу прощения, если мои слова показались Вам обидными, я не хотел никого обижать. Пояснение: если я сказал, что код работает, это значит, в нём нет логических или синтаксических ошибок, но не то, что результат его работы верный.

2 ptr:
Интересный вопрос. Я знаю точно, что этот протокол открытый и серверы должны отвечать на запросы. У сервера нет возможности отключать обработку как определённых запросов, так и обработку всех подобных запросов в принципе - это не настраивается. Формат запроса тоже не мог поменяться, или, по крайней мере, существует обратная совместимость запросов. При тестировании на локальном сервере тоже не удаётся получить ответ на некоторые запросы, но раньше я получал от него ответы на все запросы, а в сервере ничего не менял. Я склоняюсь к тому, что сервер всё-таки отправляет ответ, ведь тестировал не на одном сервере. Может ли быть где-то промежуточный буфер, который меньшего размера, чем получаемые данные? Если может быть, то как в него залезть?
PM MAIL   Вверх
sOckets
Дата 2.9.2006, 09:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


ЖгуПоПонедельникам
**


Профиль
Группа: Участник
Сообщений: 298
Регистрация: 24.8.2006
Где: ws2.lib

Репутация: нет
Всего: 2



Ничего страшного , просто мне показалось что вам помогли , вопрос решён, а в опциях вы не отметили.Прости меня за наглость smile 


--------------------
Я Будущий сотрудник Google Inc. Юзаем Google Code Search для поиска исходников. Юзаем GMail как почту.
PM   Вверх
ptr
Дата 2.9.2006, 14:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 661
Регистрация: 31.5.2006
Где: Новосибирск

Репутация: 9
Всего: 14



Apel, ну ты посмотри приходят ли данные (например с помощью Ethereal).


--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
Apel
Дата 4.9.2006, 15:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 30.8.2006

Репутация: нет
Всего: нет



так-с! Скачал программу. Установил, сделал фильтр по UDP, включил монитор и отправил запрос. Далее я не пойму: либо данные отправляются не те, что я отправляю, либо серверы не отвечают. Там, где в пакете данные вместо конца, например, 
Код

FF FF FF FF 64 65 74 61 69 6C 73 // ASCII яяяяdetails
[/co=nocolor]

de] Такое:
Код

FF FF FF FF 64 00 00 00 00 00 00 // ASCII яяяяd......

Если данные уходят неправильные, неудивительно, что нет ответа. Но более длинные запросы выполняются правильно. Мистика какая-то.

Это сообщение отредактировал(а) Apel - 4.9.2006, 15:35
PM MAIL   Вверх
dumb
Дата 4.9.2006, 15:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 1
Всего: 158



в sendto строка отдается правильная?
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0572 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.