Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.04.01;
Скачать: CL | DM;

Вниз

Как задать TimeOut на TcpClient.Connect   Найти похожие ветки 

 
skosenok ©   (2006-10-17 11:23) [0]

Если устройство подключено в сеть то TcpClient.Connect обрабатывается быстро

Если устройство отключено то TcpClient.Connect ждет очень долго пока выдаст результат

Как ограничить время ожидания когда устройство отключено.


 
Сергей М. ©   (2006-10-17 11:26) [1]

см. TcpClient.BlockMode = bmNonBlocking.


 
skosenok ©   (2006-10-17 13:16) [2]

у меня соединение при bmNonBlocking вообще не устанавливается для включенного устройства

какие еще варианты?


 
Сергей М. ©   (2006-10-17 13:24) [3]

Кто такой "включенный устройств" ?


> у меня соединение при bmNonBlocking вообще не устанавливается


Да не ври уже.
Если сервер активен и доступен, то при любом BlockMode соединение должно быть успешно установлено. Об этом факте известит событие OnConnect.


 
skosenok ©   (2006-10-17 13:40) [4]

простой пример - кидаю на форму TcpClient и TcpServer
устанавливаю одинаковые LocalHost и LocalPort
сразу активирую TcpServer

выполняю код:

if TcpClient1.Connect then Application.MessageBox("Есть связь","!") else Application.MessageBox("Нет связи","!")

при TcpClient.bmNonBlocking - нет связи
при TcpClient.bmBlocking - есть связь

TcpClient.OnConnect - соответственно также реагирует.

bmNonBlocking - асинхронная передача
возможно я что-то делаю не так... те мне надо после TcpClient.Connect например заснуть на TimeOut и потом проверить TcpClient.Connected

где я ошибся?


 
skosenok ©   (2006-10-17 13:45) [5]

дополнение - обмен данными у меня должен быть синхронным


 
Сергей М. ©   (2006-10-17 13:48) [6]


> где я ошибся?


Здесь:


> bmNonBlocking - асинхронная передача


bmNonBlocking означает не только асинхронную приемопередачу, но и асинхронный коннект.

При асинхронном коннекте единственным достоверным фактом его успешного установления является факт возбуждения события OnConnect. Ранее чем возникнет это событие нет никакого резона пыжиться с приемом-передачей.


 
Сергей М. ©   (2006-10-17 13:49) [7]


> skosenok ©   (17.10.06 13:45) [5]


Синхронным по отношению к чему/кому ?


 
skosenok ©   (2006-10-17 13:58) [8]

> Сергей М. ©   (17.10.06 13:49) [7]

по отношению к серверу... но судя по твоему ответу это ни какого не имеет отшения к коннекту

так в чем у меня тогда проблема... если в эксперименте (примере который я привел)  OnConnect не вызывается?


 
Сергей М. ©   (2006-10-17 14:33) [9]


> skosenok ©   (17.10.06 13:58) [8]



> по отношению к серверу


Это как ?

Синхронность в дан.случае не подразумевает ни "сервер" ни "клиент".
Синхронность здесь подразумевает следующее: если ты вызвал одну из ф-ций приема/передачи, то инструкции, следующие за этим вызовом, будут выполнены лишь после того, как будет выполнен фактический ввод/вывод в том или ином объеме запрошенных к вводу/выводу данных.


 
skosenok ©   (2006-10-17 14:56) [10]

это всё понятно...

я единственное спрашиваю - где я ошибся в примере... почему не работает?


 
Сергей М. ©   (2006-10-17 16:21) [11]

Метод Connect() в неблок.режиме запускает операцию коннекта и немедленно возвращает управление.

Об успешном завершении этой операции сообщит событие OnConnect, о неуспешном - OnError.

Что не понятно ?


 
skosenok ©   (2006-10-17 17:25) [12]

То, что как я уже сказал успешность не сообщается OnConnect при bmNonBlocking
а при bmBlocking  все пучком!


 
Сергей М. ©   (2006-10-18 08:38) [13]

Значит ты просто не дожидаешься события OnConnect.

Приводи конкретный код ...


 
skosenok ©   (2006-10-18 11:30) [14]

код - то что я уже описывал пример

пришли мне свой адрес на skosenok@mail.ru


 
Сергей М. ©   (2006-10-18 11:55) [15]


> код - то что я уже описывал пример


Из этого примера совершенно не понятны твои действия следом за строчкой if TcpClient1.Connect then ...


 
skosenok ©   (2006-10-18 15:54) [16]

просто... не срабатывает событие при bmNonBlocking

procedure TForm1.TcpClientConnect(Sender: TObject);
begin
Application.MessageBox("Есть связь","!")
end;


 
Сергей М. ©   (2006-10-18 16:03) [17]


> skosenok ©   (18.10.06 15:54) [16]


Значит у тебя ошибка в программе.


 
skosenok ©   (2006-10-19 10:32) [18]

ага в 10 строке....

если ты такой умный что не можешь повторить пример который я говорил:

простой пример - кидаю на форму TcpClient и TcpServer
устанавливаю одинаковые LocalHost и LocalPort
сразу активирую TcpServer

выполняю код по нажатию клавиши: TcpClient.Connect

событие при при bmNonBlocking не срабатывает
procedure TForm1.TcpClientConnect(Sender: TObject);
begin
Application.MessageBox("Есть связь","!")
end;

что сложного... тормозить... или сам попробуй или вышли мне свое мыло (чтобы не светить) чтобы я тебе это скинул если лень... или ты струхнул гений?!?


 
Dmitrij_K   (2006-10-19 10:49) [19]

skosenok не кричи.
Да, в TCPClient при bmNonBlocking не срадатывает OnConnect.
Почему? потому что код такой x!@#$, что легко посмотреть по F7+F8.
Просто пользуйся друким компанентом


 
SpellCaster   (2006-10-19 11:01) [20]


> Dmitrij_K

Т.е. TCPClient глюкаво написан? Хорошо, что не стал его юзать...


 
Dmitrij_K   (2006-10-19 11:06) [21]


> Т.е. TCPClient глюкаво написан

как это еще назвать? в справке ничего не нашел по поводу OnConnect для bmNonBlocking


 
Сергей М. ©   (2006-10-19 11:11) [22]


> skosenok ©   (19.10.06 10:32) [18]


Хамишь, парниша.

uses Winsock;
..

procedure TForm1.TcpClient1Connect(Sender: TObject);
begin
 showmessage("connect")
end;

procedure TForm1.TcpClient1Error(Sender: TObject; SocketError: Integer);
var
 FDSet: TFDSet;
 TimeVal: TTimeVal;
begin
 if socketerror <> WSAEWOULDBLOCK then
   showmessage("error: " + inttostr(socketerror))
 else begin
   FD_ZERO(FDSet);
   FD_SET(tcpclient1.handle, FDSet);
   TimeVal.tv_sec := 0;
   TimeVal.tv_usec := 500; //&#238;&#230;&#232;&#228;&#224;&#229;&#236; &#234;&#238;&#237;&#237;&#229;&#234;&#242;&#224; &#237;&#229; &#225;&#238;&#235;&#229;&#229; 500 &#236;&#241;
   case select(0, nil, @FDSet, nil, @TimeVal) of
     0: begin
         showmessage("");
         tcpclient1.Close;
        end;
     SOCKET_ERROR: showmessage("error: " + inttostr(WSAGetLastError));
   else
     tcpclient1.OnConnect(self);
   end;
 end;
end;


 
Сергей М. ©   (2006-10-19 11:16) [23]

TTCPClient написан нормально.
Но поскольку он позиционируется как кроссплатформенный компонент, в нем не реализована логика асинхронных нотификаций о транспортных событиях гнезда, ибо она специфична лишь для Win-платформы.
Т.е. в неблок.режиме для получения полной функциональной аналогии с TClientSocket требуется чуть-чуть подумать головой и приложить ручки в части реализации недостающих (но столь привычных) возможностей.


 
Сергей М. ©   (2006-10-19 11:17) [24]

Пардон..

procedure TForm1.TcpClient1Error(Sender: TObject; SocketError: Integer);
var
 FDSet: TFDSet;
 TimeVal: TTimeVal;
begin
 if socketerror <> WSAEWOULDBLOCK then
   showmessage("error: " + inttostr(socketerror))
 else begin
   FD_ZERO(FDSet);
   FD_SET(tcpclient1.handle, FDSet);
   TimeVal.tv_sec := 0;
   TimeVal.tv_usec := 500; //ожидаем коннекта не более 500 мс
   case select(0, nil, @FDSet, nil, @TimeVal) of
     0: begin
         showmessage("");
         tcpclient1.Close;
        end;
     SOCKET_ERROR: showmessage("error: " + inttostr(WSAGetLastError));
   else
     tcpclient1.OnConnect(self);
   end;
 end;
end;


 
Dmitrij_K   (2006-10-19 11:19) [25]


> Сергей М. ©   (19.10.06 11:11) [22]

т.е. контроль неблокирующего режима возложили на нас?


 
Dmitrij_K   (2006-10-19 11:20) [26]


> Сергей М. ©   (19.10.06 11:16) [23]
>
> TTCPClient написан нормально.
> Но поскольку он позиционируется как кроссплатформенный компонент,
>  в нем не реализована логика асинхронных нотификаций о транспортных
> событиях гнезда, ибо она специфична лишь для Win-платформы.
>
> Т.е. в неблок.режиме для получения полной функциональной
> аналогии с TClientSocket требуется чуть-чуть подумать головой
> и приложить ручки в части реализации недостающих (но столь
> привычных) возможностей.
>

Ага. ясно.
спасибо


 
Сергей М. ©   (2006-10-19 11:21) [27]


> Dmitrij_K   (19.10.06 11:19) [25]


Угу... Точнее - контроль за результатами вызовов неблокирующих транспортных функций.


 
SpellCaster   (2006-10-19 12:37) [28]

Не лучше ли в таком случае заюзать tclientsocket и не парить себе мозг? ;)


 
Сергей М. ©   (2006-10-19 12:48) [29]


> SpellCaster   (19.10.06 12:37) [28]


При прочих равных условиях я бы согласился.


 
skosenok ©   (2006-10-19 12:53) [30]

>Сергей М. ©   (19.10.06 11:11) [22]

огромное спасибо... именно этого я ждал три дня
прошу прощения за излишнею эмоциональность
жаль что эта функция подключит сокет только если он был включен перед запуском установки связи (а не после в течении времени ожидания)

последний вопрос... могу ли я после успешной установки connecta вернуть значение bmBlocking без каких либо последующих проблем в обмене информацией


 
Сергей М. ©   (2006-10-19 13:04) [31]


> skosenok ©   (19.10.06 12:53) [30]


> жаль что эта функция подключит сокет только если он был
> включен перед запуском установки связи (а не после в течении
> времени ожидания)


??

Ничерта не понял ..


> могу ли я после успешной установки connecta вернуть значение
> bmBlocking без каких либо последующих проблем в обмене информацией


Нет, не можешь. К сожалению.
На то и кроссплатформенность фигурирует.


 
skosenok ©   (2006-10-19 13:20) [32]

>Сергей М. ©   (19.10.06 13:04) [31]
>Ничерта не понял .
ставим TimeOut=5000
те я вызываю connect когда еще устройство выключено... а потом на 2 секунде устройство включается... но так как оно с самого начала было выключено
связь не установиться


 
Сергей М. ©   (2006-10-19 13:52) [33]


> skosenok ©   (19.10.06 13:20) [32]


В этом случае все что ты можешь предпринять - вызывать connect() циклически в течение требуемого тебе времени.


 
skosenok ©   (2006-10-20 10:28) [34]

Вылезла последняя проблема - как убить/закрыть асинхронное (bmNonBlocking) соединение

видно Disconect не помогает

так как сколько раз я открываю соединение на столько раз и выскочит ошибка 10053 на сервере при закрытии клиента


 
skosenok ©   (2006-10-20 10:32) [35]

те под  закрытием клиента я имею ввиду завершение приложения


 
Сергей М. ©   (2006-10-20 10:33) [36]


> как убить/закрыть асинхронное (bmNonBlocking) соединение


Как и любое другое - TTcpClient.Close.


> ошибка 10053 на сервере


Значит у тебя ошибка в реализации сервера.


 
skosenok ©   (2006-10-20 10:58) [37]

>Значит у тебя ошибка в реализации сервера.
сервер - компонент TServerSocket

без единой моей строчки кода


 
skosenok ©   (2006-10-20 11:21) [38]

анализ показал что ошибка вроде происходит при очистке в клиенте вызовом WSACleanup


 
skosenok ©   (2006-10-20 11:28) [39]

Все поборол функцией closesocket(TcpClient.Handle);


 
Сергей М. ©   (2006-10-20 11:33) [40]


> skosenok ©   (20.10.06 11:28) [39]


Хм ...

Тот же вызов closesocket() происходит и при вызове метода TBaseSocket.Close.



Страницы: 1 2 вся ветка

Текущий архив: 2007.04.01;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.05 c
15-1173066915
Brc
2007-03-05 06:55
2007.04.01
Вирусы


2-1173738885
Ш-К
2007-03-13 01:34
2007.04.01
Как сохранить TBitmap в XML?


15-1173109716
muhh
2007-03-05 18:48
2007.04.01
Работа с реестром


2-1173720065
GEN++
2007-03-12 20:21
2007.04.01
Problema s perezagryzkoy


15-1173086533
MsGuns
2007-03-05 12:22
2007.04.01
Украинский футбол глазами европейцев