![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
TTcpClient
Piter © (2004-04-23 20:11:00)Я уж думал разобрался, ан нет. Ни фига, итак компонент TTcpClient.
1) Почему в неблокирующем режиме события не вызываются (OnReceive)? Возникает только сразу OnError с кодом 10035
2) почему в блокирующем режиме события ВЫЗЫВАЮТСЯ?
Digitman (2004-04-25 15:19:00) [1]
> Piter
у тебя же исх.тексты перед носом - это так трудно разобраться в них ?
Piter (2004-04-25 13:37:00) [2]никто не скажет? НЕ верю, что события там просто так...
Piter (2004-04-24 12:26:00) [3]ну просто непонятно - нафига там события реализованы вообще? Они только в заблуждение вводят, все равно не работают ...
Verg (2004-04-24 12:14:00) [4]
> Piter © (24.04.04 12:08) [18]
> я про то, что как я узнаю что пришли данные? Проверять раз
> в 10 секунд? :)
Можно и чаще.:)
Можно и select с таймаутом.
Piter (2004-04-24 12:08:00) [5]я про то, что как я узнаю что пришли данные? Проверять раз в 10 секунд? :)
Verg (2004-04-24 11:22:00) [6]
> Какой толк от неблокирующего режима?
Как какой толк?
Нет, ну если твоему потоку больше заняться нечем, как только, например, и ждать данные от соединения, при том от единственного, то оно конечно.
Все остальные твои вопросы из [16] - это не ко мне :))
Piter (2004-04-24 11:02:00) [7]Verg (24.04.04 07:10) [15]
Да, действительно. Спасибо. Тольк никак не могу понять - зачем так сделано? Какой толк от неблокирующего режима? Зачем нужны события? При неблокирующем режиме они не вызываются, при блокирующем они нафиг не нужны, тот же самый OnConnect - зачем он, если Open не вернет управление, пока не разрешится вопрос соединение произошло или нет
Verg (2004-04-24 07:10:00) [8]У этих компонентов нет "событий" в том понимании как у TClientSocket, например.
Их просто некому генерировать, кроме твоего, собственно потока. Здесь нет callback ф-ций.
В блокируемом режиме начатая операция, будь то connect, recv, accept, send не вернет управления до тех пор, пока не будет достигнут результат. Хоть положительный, хоть отрицательный.
Когда мы определяем сокет как неблокирующий, мы тем самым сообщяем ядру примерно следующее: "когда запрашиваемая нами операция ввода-вывод не может быть завершена без перевода потока в состояние ожидания, следует не переводить поток в это состояние, а вместо этого вернуть соотв. ошибку". Т.е. вызываешь connect (open), а она немедленнозавершается с SOCKET_ERROR, но при этом WSAGetLastError = WSAEWOULDBLOCK. Это значение ошибки как раз и говорит нам "операция начата, но требует времени для завершения. Заходите позже".
Теперь о компонентах. Давай разберем исходник ф-ции open у TTCPClient
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 // Конечно же при неблокирующем режиме
// FConnected будет false, почти однозначно
DoConnect; // вот здесь будет вызвано "событие" OnConnect
// если в блокирующем режиме connect будет успешен
end;
end;
Вот и получается, что "событие" OnConnect вызываешь ты же сам (твой поток) и только в блокирующем режиме.
Rouse_ (2004-04-24 01:30:00) [9]> [13] Piter © (24.04.04 00:09)
Каждому, конечно, свое, но для работы с инетом я предпочитаю использовать WinInet, для других задач уже реализацию при помощи WinSock API...
Просто не вижу смысла изобретать велосипеды...
Хотя как знать...
Piter (2004-04-24 00:09:00) [10]Rouse_ (23.04.04 23:26) [12]
а не проще ли воспользоваться WinInet?
Не проще. Вопрос в другом - а лучше ли? У него свои заморочки.
Rouse_ (23.04.04 23:26) [12]
Просто проверь свой клиент, будет ли он нормально работать с (к примеру) WinGate (и другими различными прокси...).
хм, а почему нет? Если прокси - поддерживается Basic аутентификация, в точности как у IE...
Rouse_ (2004-04-23 23:26:00) [11]> Я его использую в блокирующем режиме в своем клиенте для
> форума
Небольшой совет, а не проще ли воспользоваться WinInet?
Просто проверь свой клиент, будет ли он нормально работать с (к примеру) WinGate (и другими различными прокси...). Обычно народ жалуется за отсутствие именно этих фишек...
Rouse_ (2004-04-23 23:22:00) [12]Прежде всего реализацией...
Ну да ладно, закончим флейм, жди ответов :)
Piter (2004-04-23 23:22:00) [13]Я его использую в блокирующем режиме в своем клиенте для форума, все тип топ.
Но вот озаботился вышеозначенными вопросами... может, Цифровой Человек что подскажет
Piter (2004-04-23 23:20:00) [14]В смысле чем не понравилось?
Piter (2004-04-23 23:19:00) [15]чем?
Rouse_ (2004-04-23 23:06:00) [16]сори, перепутал с TClientSocket...
А с этим чудом, что в сабже, даже не пытался работать, уж очень не понравилось...
Piter (2004-04-23 22:59:00) [17]Ну тык я ж не использую WinApi, я использую TTcpClient и если честно ответа на поставленные вопросы я не увидел... (
Rouse_ (23.04.04 22:15) [5]
PS: Ты это уже статью начал писать?
еще нет
Rouse_ (2004-04-23 22:15:00) [18]If no error occurs, connectreturns zero. Otherwise, it returns SOCKET_ERROR, and a specific error code can be retrieved by calling WSAGetLastError.
On a blocking socket, the return value indicates success or failure of the connection attempt.
With a nonblockingsocket, the connection attempt cannot be completed immediately. In this case, connect will return SOCKET_ERROR, and WSAGetLastError will return WSAEWOULDBLOCK. In this case, there are three possible scenarios:
1. Use the selectfunction to determine the completion of the connection request by checking to see if the socket is writeable.
2. If the application is using WSAAsyncSelect to indicate interest in connection events, then the application will receive an FD_CONNECT notification indicating that the connect operation is complete (successfully or not).
3. If the application is using WSAEventSelect to indicate interest in connection events, then the associated event object will be signaled indicating that the connect operation is complete (successfully or not).
Until the connection attempt completes on a nonblocking socket, all subsequent calls to connect on the same socket will fail with the error code WSAEALREADY, and WSAEISCONN when the connection completes successfully. Due to ambiguities in version 1.1 of the Windows Sockets specification, error codes returned from connect while a connection is already pending may vary among implementations. As a result, it is not recommended that applications use multiple calls to connect to detect connection completion. If they do, they must be prepared to handle WSAEINVAL and WSAEWOULDBLOCKerror values the same way that they handle WSAEALREADY, to assure robust execution.
Ну и вообще: люби MSDN - кладезь знаний мудрых :)
PS: Ты это уже статью начал писать?
Piter (2004-04-23 20:35:00) [19]Попробую еще объяснить по пунктам:
1) настройки BlockMode = bmNonBlocking
2) После клика на Button1 происходит описанный Error
3) далее никаких событий не происходит вообще.
Piter (2004-04-23 20:33:00) [20]Забыл, вот еще:
procedure TForm1.TcpClient1Error(Sender: TObject; SocketError: Integer);
begin
Memo1.Lines.Add('Error '+inttostr(SocketError));
end;