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

Вниз

Вопрос по клиентской части   Найти похожие ветки 

 
Dmitry_177   (2007-04-22 20:13) [0]

Есть клиент-серверное приложение. Клиент отправляет на сервер определенные данные, сервер обрабатывает их и присылает клиенту ответ. Но клиент т.к. не постоянно отправляет на сервер данные, и чтобы сервер не работал в холостую с данным клиентом, если связь с ним была утеряна, сервер в минуты простоя(когда от клиента ничего не приходит), каждые 5 мин. отправляет клиенту запрос, чтобы клиент немедленно ответил на него, т.е. это для проверки связи.. так вот.. когда клиент отправляет и принимает данные, то код по нажатию той же кнопки выглядит примерно так:

send(Sock...)
recv(Sock...)
send(Sock...)
recv(Sock...)
...

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

function ThreadSocket(Param: Pointer): DWORD; stdcall;
var
 iSend: Integer;
 iRecv: Integer;
 RecvSize: Integer;
begin
 while true do
   begin
     RecvSize := recv(Sock,  iRecv, SizeOf(iRecv), 0);
     if RecvSize > 0 then
       if iRecv = CHECK then
         begin
           iSend := CHECK_OK;
           send(Sock, iSend, SizeOf(iSend), 0);
         end;
   end;
end;

Но проблема в том что этот поток работает паралельно.. и когда данные посредством recv должны придти в определенную функцию, они бывают приходят в тот поток.. и получается так что программа зависает, т.к. функция не получила ответ от сервера и продолжает его ждать... Как можно с этим бороться? Помогите пожалуйста..


 
grisme ©   (2007-04-23 07:50) [1]

на блокирующих сокетах пишешь, да?
как вариант предлагаю перейти на неблокирующие :o) там структура приложения будет такова, что такого не произойдет. а если хочется все-таки многопоточность - то надо синхронизовать потоки просто-напросто.


 
Сергей М. ©   (2007-04-23 08:12) [2]

Доп.поток тут как телеге пятое колесо.


 
Kedge ©   (2007-04-23 10:20) [3]

А, разве, у Сокетов нет события разрыва связи ? (я просто не в курсе)


 
Dmitry_177   (2007-04-23 10:35) [4]

А как тогда сделать без дополнительного потока?

Синхронизацию тоже не очень пойму как ее тут делать.. Ведь в потоке recv в цикле, цикл то можно остановить, а как это остановить recv без разрушения сокета? если только разрушением сокета, но у меня ведь в это время в процедуре какойнибудь кнопочки будет происходить передача данных по этому же сокету, так что разрушать его не подходит..


 
Dmitry_177   (2007-04-23 10:37) [5]

А как тогда сделать без дополнительного потока?

Синхронизацию тоже не очень пойму как ее тут делать.. Ведь в потоке recv в цикле, цикл то можно остановить, а как это остановить recv без разрушения сокета? если только разрушением сокета, но у меня ведь в это время в процедуре какойнибудь кнопочки будет происходить передача данных по этому же сокету, так что разрушать его не подходит..


 
Сергей М. ©   (2007-04-23 10:56) [6]


> Dmitry_177


Логика, которую ты пытаешься реализовать, вовсе не требует каких-то сложных ухищрений.

1. Сервер, акцептировав клиентское соединение, тут же инициирует 5-тиминутный таймер.

2. Если по истечению 5-ти минут сервер не получил от клиента никаких запросов, он разрывает соединение по своей инициативе - дальнейшее обслуживание "молчащего" клиента, по логике твоего сервера, лишено смысла.

3. Иначе, получив до истечения 5-ти минут от любой запрос, сервер реинициирует 5-минутный таймер, после чего анализирует содержимое запроса.
Если запрос вида "я жив", сервер ничего не делает, иначе обрабатывает запрос и возвращает клиенту результат обработки.


 
Dmitry_177   (2007-04-23 11:25) [7]

клиент соединен с сервером постоянно.. "я жив" это только для проверки связи.. если в течение 5 мин. от клиента ничего не приходило, то сервер делает таКую проверку, если все ок то серве
опять ждет 5 мин. до следующей проверки.. вот как мне в клиенте ловить этот пакет "я жив"?


 
Сергей М. ©   (2007-04-23 11:39) [8]


> если в течение 5 мин. от клиента ничего не приходило, то
> сервер делает таКую проверку


Да нашута оно нужно серверу-то ?!

Сам клиент должен беспокоится о том, чтобы регулярно подавать "признаки жизни" !
Т.е. инициатором KeepAlive-обмена должен выступать клиент, а не сервер. А у тебя им почему-то является сервер).. Что, твоему серверу больше нечем заняться, как только будить "задремавших" клиентов ?


 
Dmitry_177   (2007-04-23 14:34) [9]

а таймер на сервере реализовать с помощью select-а, естественно потом recv и все это в цикле..?


 
Сергей М. ©   (2007-04-23 14:44) [10]


> таймер на сервере реализовать с помощью select-а, естественно
> потом recv и все это в цикле..?


Как удобней, так и реализуй.


 
SpellCaster   (2007-04-23 15:18) [11]

> а таймер на сервере реализовать с помощью select-а, естественно
> потом recv и все это в цикле..?

Массив, состоящий из дескрипторов клиентских сокетов и кол-ва секунд, оставшихся до закрытия каждого из них. Один таймер, который в цикле уменьшает эти значения и если они становятся <0, убивающий соотв. сокет. ибо же можно хранить время закрытия сокета : тогда не надо будет ничего уменьшать.



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

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

Наверх




Память: 0.5 MB
Время: 0.019 c
2-1196684220
GitaROMAN
2007-12-03 15:17
2007.12.30
Delphy с самого самого начала. Как разобраться Чо мутить...


2-1196961000
FoxM
2007-12-06 20:10
2007.12.30
Как скрыть статус соединения с Интернетом с TrayBar?


2-1196942339
Алекс
2007-12-06 14:58
2007.12.30
библиотеки с классами других приложений


3-1188279724
dimaL
2007-08-28 09:42
2007.12.30
FLOAT в Firebird


2-1197037557
Nikfel
2007-12-07 17:25
2007.12.30
Как получить список процессов с путем.