Показать сообщение отдельно
Старый 10.07.2013, 17:59   #13  
konfet is offline
konfet
Снова балуюсь косаптой :)
 
143 / 50 (2) ++++
Регистрация: 23.04.2003
Адрес: Moscow
Цитата:
Сообщение от ice321i Посмотреть сообщение
Вот рабочий пример проверки соединения по определенному порту сервера, проверял на 5, должно работать и для 4:
X++:
static void ConnectToServer(Args _args)
{
    System.Net.Sockets.TcpClient tcpClient;
    ;

    tcpClient = new System.Net.Sockets.TcpClient();
...
}

В том-то и дело, что для 4-ки работает хреново
Иногда вылетает с эксепшеном, иногда без эксепшена - просто не доходит до конца кода.
И еще, помимо вылетов, важный недостаток - нельзя настроить таймаут, который определяет, сколько надо ждать ответа от удаленного сервера, перед тем как посчитать его недоступным.
Я нашел в сети простую утилитку, которая работает для серверов как внутри сети (за фаерволлом), так и вне ее. Работает примитивно, но зато надежно.
Использую прежде всего для определения доступности удаленного (связанного) SQL-сервера, по порту 1433.
Таймаут определен в три секунды, можно поставить и меньше.
Утилитку надо положить в каталог Include приложения.

X++:
#define.PingSuccess('1 successful, 0 failed')
#define.PingFailed('0 successful, 1 failed')
#WInAPI
static server boolean ping3(ServerName _ServerName, str 10 _port = '80')
{
    boolean res, xSuccess, xFailed;

//  одна секунда ожидания
    str templateStr = '-4 -n 1 -w 1 %1 %2 > %3';
    str paramStr, outputStr, commandStr;
    fileName xTCPingEXE;
    fileName xFileName, xDir;
    TextBuffer TextBuffer = new TextBuffer();
    Counter i;

    ;
    xDir = WinAPIServer::getTCPing(true);

    xTCPingEXE = WinAPIServer::getTCPing(false);
    xFileName = xDir + curUserId() + '_ping.txt';
    paramStr = strFmt(templateStr, _ServerName, _port, xFileName);
    commandStr = 'CMD /c ' + xTCPingEXE + ' ' + paramStr;

//  три секунды ожидания
    WinAPI_R::shellExecuteWait(commandStr, 3000);
    TextBuffer.fromFile(xFileName);
    outputStr = TextBuffer.getText();
    xSuccess = strscan(outputStr, #PingSuccess, 1, strlen(outputStr)) ? true : false;
    xFailed = strscan(outputStr, #PingFailed, 1, strlen(outputStr)) ? true : false;
    if (xSuccess == xFailed)
    {
        throw error("Непонятный результат пинга!");
    }

    WinAPIServer::deleteFile(xFileName);
    return xSuccess;
}
Метод, возвращающий (серверный) путь к экзешнику tcping.exe:
X++:
static server fileName getTCPing(boolean _directoryOnly = false)
{
    filename xdir, xfile;

    ;

    xdir = xInfo::directory(DirectoryType::Include) + @'TCPing\';
    xfile = xInfo::directory(DirectoryType::Include) + @'TCPing\tcping.exe';
    if (!WinAPIServer::fileExists(xfile))
    {
        throw info(strFmt('   %1', xfile));
    }
    return _directoryOnly ? xdir : xfile;
}
метод shellExecuteWait() взят отсюда.
__________________
Бесты и регарды!