C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Блокируемый сокет
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

Вернуться в Вопросы программирования в C++Builder