Форум: "Сети";
Текущий архив: 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.47 MB
Время: 0.007 c