Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2007.12.30;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.006 c
2-1196849548
хоме
2007-12-05 13:12
2007.12.30
Как подставить переменную в SQL запрос?


15-1196016368
@!!ex
2007-11-25 21:46
2007.12.30
Прокомментируйте сборку


15-1196317116
vasIZmax
2007-11-29 09:18
2007.12.30
Сбор файлов локалке


2-1196908519
Александр Семак
2007-12-06 05:35
2007.12.30
Items в TMainMenu


15-1196415745
data
2007-11-30 12:42
2007.12.30
Баланс между скоростью разработки и внедрения и качеством. Мнения





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский