На Win7 создаю сразу 64 асинхронных коннекта на 64 различные удалённые машинки (без преварительного пингования оных) и не знаю проблем. Проверяется на открытость порт Х во всей локальной сети очень быстро.
Но тоже самое не выполняется на WinXP из-за пресловутого ограничения на полуоткрытые соединения (10 штук за 1 сек). Даже принудительный вызов shutdown и closesocket не прибивают этот half-open коннект в ядре системы. Приходится ждать завершения.
Можно как то прервать ожидание ответа на SYN-запрос для конктетного сокета?
Можно ли в настройках сокета выставить какой либо таймаут на ожидание ответа на SYN-запрос?
Для уменьшения создания возможных полуоткрытых соединений пришлось предварительно проверять существование адресата.
Для этого решил посылать ARP-запрос. Правда использую не стандартную функцию SendARP, а свой асихронный вариант этой функции:
DWORD SendARPEx(IPAddr DestIP, IPAddr SrcIP, PVOID pMacAddr, DWORD dwBufSize, LPOVERLAPPED ov)
{
IPAddr inBuf[2];
NTSTATUS ns;
PIO_STATUS_BLOCK iosb;
if (!ov) return ERROR_INVALID_PARAMETER;
if (!ov->hEvent) return ERROR_INVALID_PARAMETER;
inBuf[0] = DestIP;
inBuf[1] = SrcIP;
iosb = (PIO_STATUS_BLOCK)ov;
iosb->Status = 0; // STATUS_WAIT_0
iosb->Information = 0;
ns = NtDeviceIoControlFile(
hDeviceIp_exec, // FileHandle
ov->hEvent, // Event
NULL, // ApcRoutine
NULL, // ApcContext
iosb, // IoStatusBlock
0x0012003C, // IoControlCode
inBuf, // InputBuffer
sizeof(inBuf), // InputBufferLength
pMacAddr, // OutputBuffer
dwBufSize // OutputBufferLength
);
if (ns == STATUS_SUCCESS) return ERROR_SUCCESS;
if (ns == STATUS_PENDING) return ERROR_IO_PENDING;
return RtlNtStatusToDosError(ns);
}
Но даже при наличии предварительной проверки время опроса порта Х в сети для WinXP системы занимает 92 сек (с учётом времени на ожидание закрытия полуоткрытых соединений).
В то время как на Win7 тот же самый набор IP-адресов сканируется за 14 сек.