zHz00 Untitled

вторник, 29 октября 2013
23:37 Наблюдатель
Именованные трубы (named pipe) в Windows. Две программы работают друг с другом через них. Вдруг на одном из компов после прохождения пары запросов (они прошли нормально) клиентская часть докладывает, что процесс на том конце трубы отсутствует. Постойте -- как отсутствует? Вот же он, работает!

Выяснилось, что ошибка возникает при вызове функции PeekNamedPipe. Ошибка 233.

Я говорю товарищу, который писал серверную часть (а я писал клиентскую) -- давай проверим, что труба ещё работает. GetNamedPipeHandleState. Он пишет вызов. Вызов делается регулярно в моменты простоя процесса (OnIdle). Вызов возвращает FALSE! GetLastError возвращает 87 (неверный параметр; ненавижу эту ошибку, т.к. непонятно, что она значит). Но! Труба перестаёт отваливаться! То есть: добавление неработающей проверки состояния приводит к тому, что то, что раньше не работало, начало работать. Вот оно -- наблюдатель изменяет явление!

Потом вызов был переделан, чтобы он проходил успешно, но это уже ничего не изменило.

Я бы подумал, что серверная часть закрывает трубу по таймауту, однако ещё одна программа-сервер, написанная с помощью того же класса-обёртки, работает нормально, хотя она данные пересылает ещё реже, чем 1-я. И эта на других компах тоже работала!

@темы: Программирование, Борьба с техникой

URL
Вот этим проникся :) http://wzor.net/page/crazy_web/200...
Советских людей однажды переехало дефицитом. Все еще помн...
Пока мы не делаем себя сами - все наше делается за нас, и...
http://www.haroldsplanet.co.uk/
http://www.newgrounds.com/portal/content.php?id=50323 Ж...
Кто знает нормальные маршруты в горы, чтоб людей (местых ...

30.10.2013 в 01:49

30.10.2013 в 01:49
Поэтому с пайпами лучше не связываться :) Они работают, они работают правильно, но никто не знает, как это - правильно.
Во всяком случае, нужен код серверного цикла, чтобы что-то понять.

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

А может быть, пайп существует, но когда сервер в конце делает Disconnect, он отключает всех подключенных в этот момент клиентов, а не только одного (там даже негде указать, какого).

А может, ещё что-то.

Куда проще сделать что-то вроде, в псевдокоде
WSAStartup();
s=socket(AF_INET, IPPROTO_TCP);
bind(sockaddr_in(INADDR_ANY, port));
listen(s);
while not Terminated do
StartThread(accept(s));
WSACleanup();
и
procedure ThreadProc(s); begin
if s=nil exit;
while len=recv(s, buf, bufsize) do begin
if len=0 then exit;
fifo.push(buf, len);
if fifo.len>MESSAGE_LEN then
HandleMessage(fifo.pop(MESSAGE_LEN));
end;
end;

URL

31.10.2013 в 19:38

31.10.2013 в 19:38
Мне что-то подсказывает, что вы организовали серверную работу с пайпом в один поток.
Несмотря на то что это в принципе работает - результат вообщем то непредсказуем из за внутренних блокировок, которые в принципе нельзя контролировать между процессами.
Поэтому или сразу после ConnectNamedPipe спавните ещё один листенер, или же сделайте всё по нормальному и выкиньте пайпы вообще (заодно сможете по сетке общаться, это же круче)
URL

31.10.2013 в 22:37

31.10.2013 в 22:37
Гость,
а) с пайпами тоже можно по сетке общаться! Не знали?
б) нам сетка не нужна -- каждый комплект ПО работает независимо на своём компе
в) как организована работа -- через один поток или нет -- мне неведомо. Эту часть делал не я. А в те короткие мгновения, что я лицезрел текст, я не разобрал, что там происходит. Но какая-то многопоточность там есть, 100%.
г) программа так устроена, что там больше 1 клиента у сервера быть не может в принципе.

А что, клиентскую часть нормально в один поток организовывать? А то в клиентской части данные в один поток по таймеру проверяются.

Проблема в том, что на том компе баг воспроизводился стабильно, в то время как на других компах (а именно: трёх) его не было в принципе. С серверной частью-заглушкой (вместо нормального сервера) и со вторым сервером (там ещё один сервер есть другого типа, да) всё тоже работает ок. Сервер-заглушка однопоточный. Таким образом, вряд ли это связано с однопоточностью/многопоточностью.

Тем не менее вы, наверное, правы, что надо было делать через сокеты, да уже поздно. Всё уже сделано так и чтобы переделать, придётся приложить много усилий.
URL
Добавить комментарий

Расширенная форма

Подписаться на новые комментарии