Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

событие TTcpClient.OnConnect [D7, XP]


_Андрей ©   (2009-04-24 09:45:00) 

Здравствуйте, пытаюсь через сокеты подсоединиться к FTP, использую TTcpClient с закладки Internet. Делаю так:

procedure TForm1.Button1Click(Sender: TObject);
begin
 TcpClient.LocalHost := '127.0.0.1';
 TcpClient.LocalPort := '4567';
 TcpClient.Connect
end;

procedure TForm1.TcpClientError(Sender: TObject; SocketError: Integer);
begin
 MessageBox(handle, PChar(Format('Error [%d]', [SocketError])), PChar  ('Socket'),  MB_OK or MB_ICONERROR)
end;

procedure TForm1.TcpClientConnect(Sender: TObject);
begin
 MessageBox(handle, PChar('Connect!'), PChar('Socket'),
   MB_OK or MB_ICONINFORMATION)
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 if TcpClient.Connected then TcpClient.Disconnect
end;


В неблокирующем режиме коннектится (и вызывается событие TTcpClient.OnConnect), в блокирующем выдаёт ошибку "10035", прочёл что это "не совсем ошибка", а скорее сообщение говорящее о том что операция не может быть выполнена немедленно. "Ок, как скажете...". Непонятно же почему не вызывается событие TTcpClient.OnConnect, то есть непонятно как же мне узнать о факте соединения... подскажите, плиз, как быть...


Сергей М.   (2009-04-24 15:09:00) [1]


> откуда ж тогда он это брал, с "прошлых коннектов" сокета?


Зачем  ? С этого коннекта и взял - сервер-то не молчит.. Сразу после коннекта сервер представился, по всем, тэкскэть, канонам FTP)..

Я тут немного "затормозил" - упустил из виду, что речь идет конкретно об FTP.
Т.е. о частномслучае, в котором WaitForData м.б. в принципе использован для обнаружения факта состоявшегося коннекта.

А в общемслучае WaitForData для этой цели неприменим по причине [6]


_Андрей   (2009-04-24 15:01:00) [2]

хм... после такого "коннекта" я вызывал Receiveln и он мне выдавал что-то типа: "220 FTP server ready и т.д.", откуда ж тогда он это брал, с "прошлых коннектов" сокета?


Сергей М.   (2009-04-24 14:39:00) [3]


> имею ввиду его использование вместо Select


Не получится.

WaitForData не может отследить факт подключения, если партнер по соединению будет молчать.


_Андрей   (2009-04-24 13:40:00) [4]

Я имею ввиду его использование вместо Select

function TBaseSocket.WaitForData(TimeOut: Integer): Boolean;
var
 ReadReady, ExceptFlag: Boolean;
 c: Char;
begin
 Result := False;
 // Select also returns True when connection is broken.
 if Select(@ReadReady, nil, @ExceptFlag, TimeOut) then
   Result := ReadReady and not ExceptFlag and
     (PeekBuf(c, sizeof(c)) = 1);
end;


Сергей М.   (2009-04-24 11:55:00) [5]


> остановился пока на использовании TcpClient.WaitWaitForData


К коннектув каком бы то ни было режиме этот метод неимеет отношения.


_Андрей   (2009-04-24 11:02:00) [6]

Да, касательно коннекта это работает, спасибо большое, ни в жизнь бы не догадался (только я остановился пока на использовании TcpClient.WaitWaitForData, более читабельный вид всё-таки)


_Андрей   (2009-04-24 10:37:00) [7]


> Ты ничего не перепутал ?


Да-да, разумеется "в неблокирующем", ошибся, извините...

По поводу TTcpClient.Handle сейчас попробую, спасибо!


Сергей М.   (2009-04-24 10:32:00) [8]


> в блокирующем выдаёт ошибку "10035"


Ты ничего не перепутал ?

Такая ошибка может возникнуть именно в неблокирующем режиме, поскольку ф-ция winsock.connect в этом режиме запускает асинхроннуюоперацию коннекта, о чем собссно и информирует код ошибки WSAEWOULDBLOCK=10035.

Вот цитата из "генофонда" c комментариями:


procedure TCustomIpClient.Open;
var
 addr: TSockAddr;
begin
 inherited Open;
 if Active and not FConnected then
 begin
   addr := GetSocketAddr(FRemoteHost, FRemotePort);
..
   FConnected := ErrorCheck(WinSock.connect(FSocket, addr, sizeof(addr))) = 0;
..
   if FConnected then
     DoConnect; //здесь вызывается обработчик события OnConnect, если он назначен
 end;
end;



> как же мне узнать о факте соединения


В блокирующем режиме о факте успешного коннета сообщит либо True-результат вызова ф-ции Connect либо факт вызова обработчика OnConnect

В неблокирующем режиме в этом компоненте все сложнее.
По факту возникновения события OnError с кодом отказа WSAEWOULDBLOCK следует имея хэндл гнезда (см. TTcpClient.Handle) вызывать циклически ф-цию select(), которая рано или поздно сообщит о факте успешного (параметр writefds) или неуспешного (параметр exceptfds) коннекта.


Наверх

Титульная страница Поиск, карта сайта Написать письмо