Я написал плагин для сканера Angry IP Scanner для определения игровых серверов half life но столкнулся с проблемой В UDP протоколе же отсутствует соединение с другим компьютером, а следовательно и таймаута. Если другой компьютер не ответит функция не завершится подскажите как сделать таймаут в UDP вот код плагина PHP: // web_detect.cpp : Defines the entry point for the DLL application. // #include<stdio.h> #include<string.h> #include<winsock2.h> #include<windows.h> #include "plugin.h" #define PLUGIN_NAME "HL Detect" #define PLUGIN_DESCRIPTION "HL Detect 1.0\nThis plugin detects which Half-Life Server is runnning on remote machines." #define PLUGIN_AUTHOR "fire64" #define PLUGIN_WEBSITE "http://csmania.ru/" #define UNKNOWN_SERVER "Has a server" #define NOT_SERVER "N/A" #define PORT 27015 #define FRMSG "\xFF\xFF\xFF\xFF\TSource Engine Query\x00" // // Info function // extern "C" __declspec(dllexport) BOOL Info(TInfoStruct *pInfoStruct) { // Check that the struct is not older than we are expecting if (pInfoStruct->nStructSize < sizeof(pInfoStruct)) return FALSE; // Initialize structure pInfoStruct->nAngryIPScannerVersion = 216; // Minimum version for this plugin to work pInfoStruct->nPluginType = PLUGIN_TYPE_COLUMN; // This plugin will appear as a new column for scanning strncpy((char*)&pInfoStruct->szPluginName, PLUGIN_NAME, sizeof(pInfoStruct->szPluginName)); // Initialize column name strncpy((char*)&pInfoStruct->szDescription, PLUGIN_DESCRIPTION, sizeof(pInfoStruct->szDescription)); // Initialize description strncpy((char*)&pInfoStruct->szAuthorName, PLUGIN_AUTHOR, sizeof(pInfoStruct->szAuthorName)); strncpy((char*)&pInfoStruct->szPluginWebsite, PLUGIN_WEBSITE, sizeof(pInfoStruct->szPluginWebsite)); return TRUE; // We have initialized structure successfully } // // Options function // extern "C" __declspec(dllexport) BOOL Options(HWND hwndParent) { // This function must show a dialog box to user with // some options. As we don't have any options in this plugin // we could just omit this function, but we will show a MessageBox // instead to remind that this function could exist MessageBox(hwndParent, "This plugin doesn't have any options yet!", "Web Detect Plugin", MB_ICONHAND | MB_OK); return TRUE; } // // Init function // extern "C" __declspec(dllexport) BOOL Init() { // This is a initialization function // It must be used to allocate internal memory // or do any other initialization stuff. // Winsock is initialized by Angry IP Scanner itself, // so we don't need to do this here return TRUE; // Plugin will be rejected if it returns FALSE on initialization } // // Finalize function // extern "C" __declspec(dllexport) BOOL Finalize() { // This is a finalize function // It must be used to free any previously // allocated memory or do any other finalization // We don't need any finalization return TRUE; } // // Case-insensitive strstr() // char *stristr(char *str1, char *str2) { char *ptr1, *ptr2; if (str1 == NULL) return NULL; if (str2 == NULL) return str1; while (*(ptr1 = str1)) { for (ptr2=str2; *ptr1 && *ptr2 && tolower(*ptr1)==tolower(*ptr2); ptr1++, ptr2++); if (*ptr2 == 0) return str1; str1++; } return NULL; } // // Function that returns smallest number, greater than 0 // char* minPositive(char* a, char* b) { if (a <= 0) return b; else if (b <= 0) return a; else return min(a, b); } void parseServerName(LPSTR szResponse, int nLength) { if ( nLength > 12) { strncpy(szResponse, UNKNOWN_SERVER, nLength); return; } else { strncpy(szResponse, NOT_SERVER, 30); } } // // The Scan function // extern "C" __declspec(dllexport) BOOL Scan(DWORD nIP, LPSTR szReturn, int nBufferLen) { WSADATA wsaData; int BufLen = 10024; char RecvBuf[10024]; if (WSAStartup(MAKEWORD(2,2), &wsaData)) { printf (" WSAStartup error: %d\n ", WSAGetLastError ( ) ); return -1; } SOCKET name_sock=socket ( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); if ( name_sock==INVALID_SOCKET ) { printf (" socket ( ) error: %d \n ", WSAGetLastError ( ) ); WSACleanup ( ); return -1; } sockaddr_in dest_addr; dest_addr.sin_family=AF_INET; dest_addr.sin_port=htons ( PORT ); dest_addr.sin_addr.s_addr = nIP; int poket= sizeof ( FRMSG )-1; sendto(name_sock, FRMSG, poket, 0,(sockaddr *) &dest_addr, sizeof(dest_addr)); sockaddr_in server_addr; int server_addr_size=sizeof (server_addr); char szResponse[512]; char *szBufferPointer = (char*) &szResponse; int nNumRead = recvfrom (name_sock, RecvBuf, sizeof(RecvBuf),0,(sockaddr *) &server_addr, &server_addr_size); closesocket (name_sock); parseServerName((char*) &szResponse, nNumRead); _snprintf(szReturn, nBufferLen, szResponse); return TRUE; }
запускаем счетчик-таймера в отдельной нитке через секунду значение инкрементируется.... каждый новый пакет обнуляет счетчик, при достижении счетчиком определенного значения сигнализируем о тайм ауте.... в твоем случае порождаем нитку с посылкой множественных пакетов с одного порта а получать будешь все подрят.... кто то не ответит(мы и не беспокоимся о них)