Jess |
Отправлено: 09.11.2004, 15:02 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 70
|
Приветствую всех...Народ подскажите как сделать правильный неблокируемый сокет...все работает ничего, только вот блокируется программа на время сканирования наглухо...это вероятно из-за того что сокет создается блокируемый ....функция сканирования:
CODE |
DWORD TForm1::ScanPorts(AnsiString ip_str, int portus){
int sock;
int err=0;
struct hostent *host=NULL;
struct sockaddr_in addr;
FILE *log;
char *logfile="LoG.txt";
ip = ip_str.c_str();
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
return -1;
memset(&addr,0,sizeof(addr));
addr.sin_family = AF_INET;
unsigned long s_adr = inet_addr(ip);
addr.sin_addr.s_addr = s_adr;
addr.sin_port = htons(portus);
sock = socket(AF_INET, SOCK_STREAM, 0);
if (s_adr == INADDR_NONE)
{
host = gethostbyname(ip);
if(host == NULL)
{
RichEdit1->Lines->Add(WSAGetLastError());
return -1;
}
memcpy(&addr.sin_addr, host->h_addr_list[0], host->h_length);
}
if (sock == INVALID_SOCKET )
{
RichEdit1->Lines->Add(WSAGetLastError());
return -1;
}
timeout(sock);
memset(buff,0,sizeof(buff));
unsigned long cou = 1; //если закоментировать эту и следующие строки то работает в блокирующем режиме если оставить их то с сокета ничего не читается (что-то типа нет конекта, но сканирование идет быстро но безрезультатно..:()
ioctlsocket(sock, FIONBIO, &cou);
int i=connect(sock,(struct sockaddr *)&addr, sizeof(addr));
if(i==0){
send(sock, "HEAD / HTML/1.0\n\n",17,0);
recv(sock, buff, sizeof(buff), 0);
RichEdit1->Lines->Add(AnsiString(ip)+"\n");
RichEdit1->Lines->Add(buff);
("+++++++++++++++++++++++++++++++++++++++++++++++++");
}
else {
RichEdit1->Lines->Add(AnsiString(ip)+"\t\t\t\t\t""Error connect");
closesocket(sock);
WSACleanup(); }
RichEdit1->Refresh();
log=fopen(logfile, "a+");
fprintf(log,"[+++++++++++++++++%s+++++++++++++++++++]\n", ip);
fprintf(log,"%s\n",buff);
fprintf(log,"\n");
fclose(log);
return 0;
}
|
За ранее признателен..............
Отредактировано Jess — 09/11/2004, 16:16
|
|
Daan |
Отправлено: 10.11.2004, 09:04 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 62
|
Для этова нада создавать отдельный поток или как-нибуть в твоей функции сделать дополнение: обработку сообщений ОС |
|
Konstantine |
Отправлено: 10.11.2004, 10:03 |
|
Мастер участка
Группа: Модератор
Сообщений: 545
|
QUOTE (Daan @ 10/11/2004, 10:06) | сделать дополнение: обработку сообщений ОС |
компонент Application Events
|
|
Jess |
Отправлено: 10.11.2004, 14:09 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 70
|
Я про потоки давно думаю....Только вот как их правильно создавать???В нете много про это написано но конкретных примеров Я не видел....мож кто подскажет или приведет примерчик с кодом ....???
|
|
Konstantine |
Отправлено: 10.11.2004, 14:25 |
|
Мастер участка
Группа: Модератор
Сообщений: 545
|
в потоке — то блокируемый....
неблокир. — это через сообщения окну.
А чем тебя соотв. компоненты не устраивают?
|
|
Daan |
Отправлено: 11.11.2004, 20:51 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 62
|
Konstantine: в потоке — то блокируемый....
А разве в потоке не выполняется параллельно программе????? |
|
Konstantine |
Отправлено: 12.11.2004, 09:27 |
|
Мастер участка
Группа: Модератор
Сообщений: 545
|
Параллельно, но поток-то блокируется...,
для того и убирается в дополтительный поток, чтоб осн. прогу не блокировало.
а НЕблокирующий сокет — он сообщения окну шлёт, когда события приходят (конект, чтение, запись, и т.д.), и в отдельном потоке не нуждается
to Jess тут недавно было... щас поищу
вот тут есть немного...
щас ещё напишу.
Отредактировано Konstantine — 12/11/2004, 10:41
|
|
Konstantine |
Отправлено: 12.11.2004, 09:58 |
|
Мастер участка
Группа: Модератор
Сообщений: 545
|
суть в следущем — в потоке есть:
конструктор, деструктор — эт соотв. настройка внутр. переменных класса (выполняется в осн.потоке)
метод Execute — который, собственно и содержит код дополнит. потока. При написании этого метода нужно время от времени проверять состояние флага Terminated, который выставляется когда из потока нужно выйти для его корректного завершения.
для связи с осн. потоком из дополнительного есть метод Sinhronize, который вызывается из доп. потока выполняется в осн. (пока в осн. он не выполнится, доп. находится в паузе).
Из осн. проги:
создание: TMyThread *thr=new TMyThread(false); // параметр указывает на то, будет ли поток на паузе сразу после создания
thr->Resume(); // снять с паузы
thr->Terminated(); // установить флаг Terminated (НЕ удаляет поток, а только "сообщает" о завершении)
thr->WaitFor(); // ждёт завершения доп.потокп
thr->Free(); // удаляет класс потока (поток уже НЕ должен выполняться)
кстати — delete thr — НЕДОПУСТИМА!!!
при обращении из доп.потока в осн. к переменным и функциям ... можно напрямую..., а к методам и свойствам (property) классов — только через Sinhronize.
Для использования синронизации в конструкторе определи свойство OnSinhronize на функцию типа: void __fastcall Sinhr(TObject* Sender), в которой и описан код синхронизации
|
|
Jess |
Отправлено: 19.11.2004, 18:38 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 70
|
Это конечно все хорошо ....но мне бы на WinAPI (через CreateThread)......для моей проги......
За ранее благодарствую...............
Отредактировано Jess — 19/11/2004, 21:59
|
|