Здравствуйте народ, я решил написать монитор для серверов 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 argc, char* argv [ ] ) { char buff [ 10*1024 ]; printf (" UDP Client \n"); //Подключение библиотеки if (WSAStartup ( 0x202, ( WSADATA *) &buff [ 0 ] )) { printf (" WSAStartup error: %d\n ", WSAGetLastError ( ) ); return -1; } //Создание сокета SOCKET name_sock=socket ( AF_INET, SOCK_DGRAM, 0 ); 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_addr, sizeof(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; }
Если размер данных превышает размер буфера для данных, то в UDP лишние данные просто отбрасываются, и устанавливается ошибка WSAEMSGSIZE. ( № 10040 ) Вот ссылка на коды ошибок http://foxpopuli.narod.ru/plb/fsox.html
это баг профиксил, теперь такая проблема, вместо содержимого пакета, прога много раз выдает ip отправителя
Поверь, одного кода на странице было достаточна Ну это тебе наверно нужно смотреть спецификацию протокола контры, если она конечно открыта, в чем я конешн сомневаюсь ( корпоративная разработка всеж). Попробуй записывать вывод пакетов в файл, а потом проанализируй нужную тебе информацию, найди смещение X в buff[X] , после которого и будет нужная тебе информация и что это за строчка такая?? PHP: buff [n]=0; если это конец строки, то он должен выглядеть вот так: PHP: buff [n]='\0';
проблема в том что printf("S=>C: %s", &buff [0]); должна выводить на экран содержимое пакета, а вместо него там ip адрес отправителя
вот описание протокола 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 Пакет первоначального запроса может уже изменился - гугли и спрашивай на тематических форумах.