PDA

Просмотр полной версии : UDP таймаут или что-то подобное


fire64
13.12.2008, 23:36
Я написал плагин для сканера Angry IP Scanner для определения игровых серверов half life

но столкнулся с проблемой

В UDP протоколе же отсутствует соединение с другим компьютером, а следовательно и таймаута.

Если другой компьютер не ответит функция не завершится

подскажите как сделать таймаут в UDP

вот код плагина


// 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;
}

Kernet
13.12.2008, 23:46
ыы,
Я гдет его уже видел xDD

Delimiter
13.12.2008, 23:53
запускаем счетчик-таймера в отдельной нитке через секунду значение инкрементируется.... каждый новый пакет обнуляет счетчик, при достижении счетчиком определенного значения сигнализируем о тайм ауте....

в твоем случае порождаем нитку с посылкой множественных пакетов с одного порта а получать будешь все подрят.... кто то не ответит(мы и не беспокоимся о них)