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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> UDP таймаут или что-то похожее, как реализовать ? 
:(
    Опции темы
fire64
Дата 14.12.2008, 09:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Я написал плагин для сканера 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;
}  

PM MAIL   Вверх
MAKCim
Дата 14.12.2008, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


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

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



SO_RCVTIMEO


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
fire64
Дата 14.12.2008, 11:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



не работает

я немного изменил код, но толку нет, всеравно функция не завершается

и еще как мне сделать условие с таймаутом ?


Код

// 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 < 6 )        
    {

        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;
    
    
    setsockopt(name_sock, SOL_SOCKET, SO_RCVTIMEO, "1", 1);
    
    
    
    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, RecvBuf);

    

    return TRUE;
}




Это сообщение отредактировал(а) fire64 - 14.12.2008, 11:14
PM MAIL   Вверх
Олег2005
Дата 14.12.2008, 11:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

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



Проще всего поставить таймаут с помощью select()
Тогда будете висеть на селекте - до истечения таймаута, а если что-то пришло в буфер UDP, то отловите событие FD_READ  и выполните прием.
PM MAIL WWW MSN   Вверх
fire64
Дата 14.12.2008, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Олег2005, большое спасибо, все работает

сделал так

добавил

Код

    fd_set fd_read, fd_error;

    timeval timeout;
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;

    fd_error.fd_array[0] = name_sock;
    fd_error.fd_count = 1;

    fd_read.fd_array[0] = name_sock;
    fd_read.fd_count = 1;


а потом

Код

    while (select(0, &fd_read, 0, &fd_error, &timeout) > 0)
    {

        nNumRead = recvfrom (name_sock, RecvBuf, sizeof(RecvBuf),0,(sockaddr  *) &server_addr, &server_addr_size);

    }


PM MAIL   Вверх
MAKCim
Дата 14.12.2008, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


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

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



fire64, 
прежде чем говорить "не работает"
читайте документацию
не так нужно делать
Код

setsockopt(name_sock, SOL_SOCKET, SO_RCVTIMEO, "1", 1);

а так
Код

int timeo = 20; /* 20 miliseconds */
setsockopt(name_sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeo, sizeof(timeo));

ну и код ошибки не забываем проверять


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

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


 




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


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

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