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

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

Использование TTcpClient [D6, Win2k]


Эл ©   (2004-01-18 23:05:00) 

Здравствуйте!
Не совсем понятно как с TTcpClient работать: событие onReceive не генерируется автоматически, как в TClientSocket, приходится "вытягивать" информацию ReceiveBuf'ом, при этом программа или не реагирует, или зацикливается - стало быть нужен отдельный Thread?


Verg   (2004-01-20 10:23:00) [1]


> Piter ©   (19.01.04 22:06) [10]
> Verg, ладно, если ты уж разобрался с этими сокетами, скажи
> - когда там возникает событие OnConenct? Или мне самому
> его надо вызывать?


В блокирующем режиме OnConnect вызовется после установления соединения. Т.е. active:=true (или просто open) заблокируется до окончания оперции соединения. После успешного установления соединения вызывается OnConnect и ф-ция Open на этом заканчивается.

В неблокирующем режиме OnConnect может вообще не возникнуть т.к. метод open скорее всего вернет управление сразу же с ошибкой WSAEWOULDBLOCK, что означает, что операция соединения успешно началась.
Чтобы определить когда соединение установилось (или попытка закончилась неудачно) вызывается метод select и когда он вернется с установленным флагом WriteReady (ах уж этот OnWrite!! :)) сокет подключился успешно и можно начинать передавать/принимат данные. Select может вернут и флаг ExceptFlag, что будет означать нудавшееся подключение. Кроме того, у select есть TimeOut....


> Сдается мне его нужно вызывать сразу после открытия сокета
> в цикле до закрытия. А чтобы программа не замерла на этом,
> делать в отдельном треде. Только вот я думал что в TTcpClient
> это все же очеловечено как-то.. в таком случае легче просто
> написать свой сокет на апи. Или юзать TClientSocket (хотя
> и у него с ReceiveBuf какие то накладки - не получилось
> считать буфер в PChar (память под строку выделил, не забыл
> ;)) )


А мне сдается, что если вы собираетесь создавать чисто виндознуюпрогу, то какого .... вы стали использовать кросс-платформенную компоненту? Зачем?
Именно TClientSocket - это то, что для вас доктор прописал :)


Эл   (2004-01-20 07:34:00) [2]


> Вот это логика... а как узнать, когда вызывать эти Receiveln?

Сдается мне его нужно вызывать сразу после открытия сокета в цикле до закрытия. А чтобы программа не замерла на этом, делать в отдельном треде. Только вот я думал что в TTcpClient это все же очеловечено как-то.. в таком случае легче просто написать свой сокет на апи. Или юзать TClientSocket (хотя и у него с ReceiveBuf какие то накладки - не получилось считать буфер в PChar (память под строку выделил, не забыл ;)) )


Piter   (2004-01-19 22:06:00) [3]

Verg, ладно, если ты уж разобрался с этими сокетами, скажи - когда там возникает событие OnConenct? Или мне самому его надо вызывать?


Verg   (2004-01-19 19:14:00) [4]

Да, и еще посмотри в хелпах про сокеты темы:
1. Что такое FD_SET и связанные с ней макросы.
2. Блокирующий и неблокирующий режимы сокетов
3. Фукции recv/send/recvfrom/sendto
4. Фукцию select и для чего она нужна

загляни в исходник, в конце концов (Socket.pas) и сравни его с исходником ScktComp.pas. Особенно обрати внимание на слово Linux.

Может жизнь не такой веселой покажется, но более сознательной - это точно....


Verg   (2004-01-19 19:08:00) [5]


> Piter ©   (19.01.04 18:59) [7]
> Вот это логика... а как узнать, когда вызывать эти Receiveln?
>
> И еще что интересно - событие OnConnect тоже с моей подачи
> возникает? :)))


1. Зря смеешься. Это так и есть на самом деле.
2. Когда и чего вызывать определяется функцией select


Piter   (2004-01-19 18:59:00) [6]

Вот это логика... а как узнать, когда вызывать эти Receiveln?

И еще что интересно - событие OnConnect тоже с моей подачи возникает? :)))


Verg   (2004-01-19 16:53:00) [7]


> Piter ©   (19.01.04 16:43) [5]
> Нафига там события, если они никогда не возникают?


Они возникают. Но только "с твоей подачи".
К приемру,
когда ты вызываешь метод Receiveln(символ(ы) конца строки происходит прием порций пока не встертятся эти самые символы КС и по мере приема порций будет вызываться OnReceive, ну например, чтобы ты мог "фильтровать" входной поток.


Piter   (2004-01-19 16:43:00) [8]

Нафига там события, если они никогда не возникают? Вот в чем вопрос. Странно это. Может, Digitman пояснит...


Verg   (2004-01-19 16:31:00) [9]


> - стало быть нужен отдельный Thread?


Выходит, что нужен.

Эти компоненты не используют наворотов WINSock. Сделано это для обеспечения кросс-платформы.
Так что, никаких WSAAsync(Event)Select.... Чистые UNIX-стиль сокеты...


Piter   (2004-01-19 16:00:00) [10]

Фиг знает что происходит. У меня тоже событие не возникает. Да и OnConnect не работает... какой-то левый компонент.

Могу только посоветовать использовать другие компоненты


Эл   (2004-01-19 08:01:00) [11]

поставил bmNonBlocking. onRecieve по-прежнему не работает.

приведу код:

var sock: TTcpClient;
procedure TForm1.FormClick(Sender: TObject);
begin
 sock:=TTcpClient.Create(self);
 sock.RemoteHost:='localhost';
 sock.RemotePort:='6667';
 sock.OnReceive:=Receive;
 sock.BlockMode:=bmNonBlocking;
 sock.Open;
end;

procedure TForm1.receive;
begin
 showmessage('data recvd!');
end;


при этом firewall показывает, что соединение установлено и ему отправлено 201 байт.


Piter   (2004-01-19 01:05:00) [12]

Эх, ну если событие OnReceive там есть - значит не просто так?

Есть такое свойство у этого компонента BlockMode - вот и поставь там bmNonBlocking.

А если работать с блокирующими сокетами - то да, в отдельный поток.


Наверх

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