Довольно долго бьюсь с одной проблемой, и все никак не могу разобраться. Есть программа, которая выполняет параллельно, в 100 потоках взаимодействие с разными TCP-серверами. Взаимодействие осуществляется из разных библиотек - моих и не моих. Для простоты возьмем следующий алгоритм работы : программа выполняет функции порт-сканнера, используя connect. Мы имеем 1000 хостов, из которых 50 хостов рабочие. Так же имеем сервер (наш, 100% рабочий, не загруженный, стоящий в соседней стойке, с каналом 1гигабит до хоста на котором запущена программа). Программа в 100 потоках осуществляет следующее : взяли сервер из списка. выполнили к нему функцию ws2_32!connect (подключились) выполнили посылку\прием некоторых данных (допустим комманды http-протокола "GET / HTTP/1.0\n\r\n\r") В зависимости от успешности этой операции отрепортили на сервер статистики через XMLRPC : репортинг: подключились через ws2_32!connect к серверу статистики (помним, коннект быстрый, сервер рядом и не нагружен). отослали данные через HTTP_POST отключились. завершили поток. Далее вопрос. Из 1000 хостов в списке мы имеем только 50 рабочих, т.е. 0.5% . Следовательно у нас есть 90-100 параллельно висящих в ожидании вызовов ws2_32!connect в разных потоках. И при этом другие коннекты из этого процесса, и даже из других (!!!) процессов (из других процессов редко, но случается) тоже висят! Т.е. я не могу подключиться к своему серверу статистики. У меня возникает такое ощущение, что в винсоке или еще ниже (в стеке протоколов) есть какой-то семафор, который не позволяет держать много вызовов connect в стадии подключения. Что местные гуру скажут по этому поводу?
В драйвере tcpip.sys есть ограничение на число полуоткрытых соединений. Нужно установить патч снимающий это ограничение. Ищи по имени EvID4226Patch223d-en.zip. З.Ы. использовать блокирующие сокеты для таких целей очень хреново.
Биндь свой хост. Используй ioctlsocket(sockraw,SIO_RCVALL,flag) для приема пакетов из вне. Отключай SharedAccess. Создавай Raw сокет. Посылай SYN. И работай с IP протоколом.
Решение проблемы: Код (Text): SCHandle:=OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS); if SCHandle<>0 then begin SHandle:=OpenService(SCHandle,'SHAREDACCESS',SERVICE_STOP); if SHandle<>0 then begin QueryServiceStatus(SHandle,ServiceStatus); if ServiceStatus.dwCurrentState=SERVICE_RUNNING then ControlService(SHandle,SERVICE_CONTROL_STOP,ServiceStatus); CloseServiceHandle(SHandle); end; CloseServiceHandle(SCHandle); end; Далее посылаем куда чего хотим.