recvfrom ( ) error: 10040

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by fire64, 20 Jun 2008.

  1. fire64

    fire64 Elder - Старейшина

    Joined:
    1 Apr 2008
    Messages:
    251
    Likes Received:
    22
    Reputations:
    5
    Здравствуйте народ, я решил написать монитор для серверов Conter Strike
    сделал небольшую програмку UDP клиент с использованием сокетов

    программа отсылает пакет, но при приеме ответа сообщает об ошибке recvfrom ( ) error: 10040

    вот код

    PHP:
    #include<stdio.h>
    #include<string.h>
    #include<winsock2.h>
    #include<windows.h>


    #define PORT  27015
    #define SERVERADDR  "10.207.112.107"

    int main int argcchar*  argv [ ] )
    {
                  
    char buff 10*1024 ];
                  
    printf  (" UDP Client \n");
            
    //Подключение библиотеки
                  
    if (WSAStartup 0x202, ( WSADATA  *) &buff ] ))
                  {
                                          
    printf  (" WSAStartup     error:   %d\n "WSAGetLastError ( ) );
                                          return  -
    1;
                   }
                 
    //Создание сокета
                   
    SOCKET  name_sock=socket AF_INETSOCK_DGRAM);
                   if   ( 
    name_sock==INVALID_SOCKET )
                   {
                                          
    printf (" socket ( ) error: %d \n "WSAGetLastError ( ) );
                                          
    WSACleanup ( );
                                          return -
    1;
                   }
                   
    //Обмен сообщений с сервером
                  
    HOSTENT  *hst;
                  
    sockaddr_in  dest_addr;

                  
    dest_addr.sin_family=AF_INET;
                  
    dest_addr.sin_port=htons PORT );
                   
    //Определение IP-адреса узла
                   
    if    (inet_addr SERVERADDR )) dest_addr.sin_addr.s_addr=inet_addr SERVERADDR );
                  else
                             if   ( 
    hst=gethostbyname SERVERADDR )) dest_addr.sin_addr.s_addr=((unsigned long  **)
                                       
    //функция  gethostbyname  ожидает на входе ТОЛЬКО доменные имена
                                                                                                                                     
    hst->h_addr_list)[0][0];
                  else
                             {
                                           
    printf ("Unknown host:  %d \n"WSAGetLastError ( ));
                                           
    closesocket name_sock );
                                           
    WSACleanup ( );
                                           return -
    1;
                              }
                   while (
    1)
                    {
                               
    //Чтение сообщения с клавиатуры
     //                          printf (""); fgets (&buff [0], sizeof (buff) -1, stdin);
       //                        if (!strcmp(&buff [0], "quit \n")) break;

                                
    char buff[100] = "яяяяTSource Engine Query";




                               
    //передача сообщений на сервер
                               
    sendto(name_sock, &buff [0], strlen ( &buff [0] ), 0,(sockaddr  *)  &dest_addrsizeof(dest_addr));
                               
    //Прием сообщений с сервера
                               
    sockaddr_in   server_addr;
                               
    int server_addr_size=sizeof (server_addr);

                               
    int  n=recvfrom (name_sock, &buff [0], sizeof(buff)-1,0,(sockaddr  *) &server_addr, &server_addr_size);
                               if  ( 
    n==SOCKET_ERROR)
                               {
                                            
    printf ("recvfrom ( ) error:  %d\n"WSAGetLastError ( ) );
                                            
    closesocket(name_sock);
                                            
    WSACleanup ( );
                                            return -
    1;
                               }
                               
    buff [n]=0;
                               
    //Вывод принятого сообщения с сервера на экран
                               
    printf("S=>C: %s", &buff [0]);
                     }
                     
    //Выход
                    
    closesocket (name_sock);
                    
    WSACleanup ( );
                     return  
    0;
    }

     
  2. _empty

    _empty Elder - Старейшина

    Joined:
    22 Mar 2008
    Messages:
    62
    Likes Received:
    17
    Reputations:
    5
    Если размер данных превышает размер буфера для данных, то в UDP лишние данные просто отбрасываются, и устанавливается ошибка WSAEMSGSIZE. ( № 10040 ) :)

    Вот ссылка на коды ошибок http://foxpopuli.narod.ru/plb/fsox.html
     
    #2 _empty, 20 Jun 2008
    Last edited: 20 Jun 2008
  3. fire64

    fire64 Elder - Старейшина

    Joined:
    1 Apr 2008
    Messages:
    251
    Likes Received:
    22
    Reputations:
    5
    это баг профиксил, теперь такая проблема, вместо содержимого пакета, прога много раз выдает ip отправителя
     
    #3 fire64, 20 Jun 2008
    Last edited: 20 Jun 2008
  4. _empty

    _empty Elder - Старейшина

    Joined:
    22 Mar 2008
    Messages:
    62
    Likes Received:
    17
    Reputations:
    5
    Поверь, одного кода на странице было достаточна :)

    Ну это тебе наверно нужно смотреть спецификацию протокола контры, если она конечно открыта, в чем я конешн сомневаюсь ( корпоративная разработка всеж). Попробуй записывать вывод пакетов в файл, а потом проанализируй нужную тебе информацию, найди смещение X в buff[X] , после которого и будет нужная тебе информация :)

    и что это за строчка такая??

    PHP:
    buff [n]=0;
    если это конец строки, то он должен выглядеть вот так:

    PHP:
    buff [n]='\0';
     
    #4 _empty, 20 Jun 2008
    Last edited: 20 Jun 2008
  5. fire64

    fire64 Elder - Старейшина

    Joined:
    1 Apr 2008
    Messages:
    251
    Likes Received:
    22
    Reputations:
    5
    проблема в том что printf("S=>C: %s", &buff [0]); должна выводить на экран содержимое пакета, а вместо него там ip адрес отправителя
     
  6. _empty

    _empty Elder - Старейшина

    Joined:
    22 Mar 2008
    Messages:
    62
    Likes Received:
    17
    Reputations:
    5
    Попробуй вместо
    PHP:
    printf("S=>C: %s", &buff [0]);

    printf("S=>C: %s"buff);
     
  7. fire64

    fire64 Elder - Старейшина

    Joined:
    1 Apr 2008
    Messages:
    251
    Likes Received:
    22
    Reputations:
    5
    всеравно вместо содержимого пакета S=>C: ****m10.207.112.107:27015
     
  8. Delimiter

    Delimiter Banned

    Joined:
    8 Apr 2005
    Messages:
    317
    Likes Received:
    173
    Reputations:
    12
    в лабах я давал разборку в шестнадцатиричных кодах блоков приема
     
    1 person likes this.
  9. izlesa

    izlesa Elder - Старейшина

    Joined:
    3 Jan 2008
    Messages:
    112
    Likes Received:
    32
    Reputations:
    5
    вот описание протокола CS:S
    http://www.int64.org/docs/gamestat-protocols/source.html
    какой свежести не знаю. Изменения дальше гугли сам.

    Код ужасен по стилю, некоторые извращения убивают => Бери К&R или Прата и долго медитируй.

    Во вторых.
    Насколько я понял по описалову сначало нужно запросить сервер пакетом вида - FF FF FF FF 54 != твоей строке символов тк ты передаёшь массив из 100 символов. И при инициализации строкой не указывай размер массива. в итоге чтото типо этого -
    char buffer[] = "\xFF\xFF\xFF\xFF\x54";
    при передаче передавай на один символ меньше, чтобы исключить \0 - sizeof(buffer) - 1
    Пакет первоначального запроса может уже изменился - гугли и спрашивай на тематических форумах.