Перейти до

Broken Pipe!


Рекомендованные сообщения

подскажите что такое, и как его лечить

(строка 184)2007-06-11 23:06:59 -- Broken pipe!

2007-06-11 23:06:59 -- Broken pipe!

2007-06-11 23:06:59 -- Broken pipe!

.....................................................

.....................................................

2007-06-11 23:07:00 -- Broken pipe!

2007-06-11 23:07:00 -- Broken pipe!

(строка 1673)2007-06-11 23:07:00 -- Broken pipe!

Ссылка на сообщение
Поделиться на других сайтах
  • 5 months later...

короче ситуация такая:

 

захожу в кофигуратор

правлю юзера

сохраняю

обновляю

во время обновления пытаюсь снова открыть юзера

конфигуратор зависает

в логе стг обнаруживается множество broken pipe

 

что интересно, проблемы была как на версии 2.0, так и на 2.403b сейчас.(bsd410)

Ссылка на сообщение
Поделиться на других сайтах

судя по теме, там устраняется баг с фаерфоксом, а у меня текстовая БД. Боязно накатывать последнюю бетту. Кто нить может точно сказать про эту проблему?

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

Этот баг точно проявлялся при работе с firebird. В остальных случаях он был или очень редкий или совсем не проявлялся. Непосредственно с firebird он никак не связан, а связан с логирование работы сервера. Можете просто закоментировать код функции printfd в файле common.cpp библиотеки common.lib и пересобрать проект (если у вас stg с динамическими библиотеками - пересобрать библиотеку и положить ее вместо старой). Это должно помочь.

Ссылка на сообщение
Поделиться на других сайтах

Баг одновременных запросов к сокету конфигуратора, в том числе и из одного конфигуратора у меня наблюдается даже на последней бете с аналогичными симптомами.

Ссылка на сообщение
Поделиться на других сайтах

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

Ссылка на сообщение
Поделиться на других сайтах

Стоп-стоп! Конфигуратор работает по TCP и не держит сессию дольше чем необходимо для трансфера данных. Если в этот момент кто-то еще лезет с подключением - он попадает в очередь на listen до следующего accept. Откуда тут могут быть SIGPIPE?

Хм. Посмотрел на плагин конфигуратора. rsconf.cpp: 126

res = listen(listenSocket, 0);

Попробуйте 0 заменить, скажем, на 16.

man listen:

The  backlog  parameter defines the maximum length the queue of pending connections may grow to.  If a connection request arrives with the queue full the client may receive an error with an indication of  ECONNREFUSED  or,  if  the underlying protocol supports retransmission, the request may be ignored so that retries succeed.

Но все равно не понятно откуда там SIGPIPE.

Ссылка на сообщение
Поделиться на других сайтах

Да, в очередь он устанавливается, но при большом числе пользователей, обновление списка достаточно длительный процесс (~20-30 сек) и конфигуратор на это время подвисает, часто намертво и приходиться его убивать после чего плодятся Broken pipe.

 

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

 

Думаю правильнее переписать систему на параллельную обработку запросов конфигураторов.

Ссылка на сообщение
Поделиться на других сайтах

 

int listen (

 

    SOCKET s,

    int backlog

  );

 

 

Parameters

 

s

 

[in] A descriptor identifying a bound, unconnected socket.

 

backlog

 

[in] The maximum length to which the queue of pending connections can GROW. If this value is SOMAXCONN, then the underlying service provider responsible for socket s will set the backlog to a maximum "reasonable" value.

 

 

Думаю что res = listen(listenSocket, SOMAXCONN); или res = listen(listenSocket, 16) должно помочь сегодня ночью перекомпилим - завтра скажу

Ссылка на сообщение
Поделиться на других сайтах

первое что мы делали

 

пробывали держать открытый сокет и в конфигураторе

запустить обновление.процедура обновления "висит",но при освобождении сокета

корректно продолжает обновлять список.

 

То-есть запросы на сокет стоят в ожидании и выполняются при достижении своей очереди

так как в серверной части используется работа с сокетами в режиме "O_NONBLOCK"

 

для организации многопоточной обработки с сокетами прийдется переделывать очень много кода

 

для каждого соединия создавать свои нити и корректо их обрабатывать - но такая схема сильно

усложнит сам код.

 

посему с эти нужно смириться и принаровиться.

 

 

Теперь стояла задача заставить сервер вываливать сообщение Broken pipe

что мы не делали у нас ничего не получилось.

 

И здесь на помощь к нам пришла Ирина, вот она явно заметила когда конфигуратор помирал.

А помирал он тогда, когда во время обновления списка она пыталась изменить данные пользователя

 

лезем в коды и что мы видим.

 


int TEditUserForm::SendRequest(list<String> & req)
{
NETTRANSACT nt;
nt.SetServer(settings.server);
nt.SetServerPort(settings.serverPort);
nt.SetLogin(admin.GetLogin());
nt.SetPassword(admin.GetPassword());
nt.SetRxCallback(UsersParseReply);

if (nt.Connect() != st_ok)
   {
   admin.LogOut();
   MessageDlg(nt.GetError(), mtError, TMsgDlgButtons() << mbOK, 0);
   return -1;
   }
else
   {
   if (nt.Transact(&req) != st_ok)
       {
       admin.LogOut();
       MessageDlg(AnsiString("Сервер сообщает об ошибке:\n") + AnsiString(nt.GetError()),
           mtError, TMsgDlgButtons() << mbOK, 0);
       return -1;
       }
   }

nt.Disconnect();

return 0;

 

Вызов nt.Disconnect() - происходит в любом случае установили мы соединение с сервером или нет.

 

Но как я сказал раньше в этот момент идет обновление списка,казалось бы что происходит,

а происходит следующее: соединение мы не смогли установить и вызывам сразу nt.Disconnect();

 

смотрим что у нас там

 


int NETTRANSACT::Disconnect()
{
closesocket(outerSocket);
WSACleanup();
return 0;

 

WSACleanup() - функция завершает работу программы с библиотекой гнезд Ws2_32.dll.

 

вот и ответ !!!!

 

 

Есть два метода решения

 

1. Метод очередной затычки:

 


int TEditUserForm::SendRequest(list<String> & req)
{
NETTRANSACT nt;
nt.SetServer(settings.server);
nt.SetServerPort(settings.serverPort);
nt.SetLogin(admin.GetLogin());
nt.SetPassword(admin.GetPassword());
nt.SetRxCallback(UsersParseReply);

if (nt.Connect() != st_ok)
   {
   admin.LogOut();
   MessageDlg(nt.GetError(), mtError, TMsgDlgButtons() << mbOK, 0);
   return -1;
   }
else
   {
   if (nt.Transact(&req) != st_ok)
       {
       admin.LogOut();
       MessageDlg(AnsiString("Сервер сообщает об ошибке:\n") + AnsiString(nt.GetError()),
           mtError, TMsgDlgButtons() << mbOK, 0);
       return -1;
       }
   nt.Disconnect();
   }

return 0;

 

то есть ставим nt.Disconnect(); на свое место. Но такая же фигня может вылезти еще где-то

 

2. Правильный метод:

 

int NETTRANSACT::Disconnect()
{
closesocket(outerSocket);
// Нужно убрать из метода
WSACleanup();
// до сих пор
return 0;

 

 

int NETTRANSACT::Connect()
{
int ret;

// Нужно убрать из конструктора
ret = WSAStartup(MAKEWORD(1, 1), &wsaData);
if (ret)
   {
   strcpy(errorMsg, WSASTARTUP_FAILED);
   return st_conn_fail;
   }

// до сих пор

 

 

И теперь разово вызвать эти обе функции - но к сожалению на си Я не знаю где их вставить-

но то что их нужно выкинуть из класса - это уж точно

 

на делфе они у меня вставлены в секцию инициализации и финализации соответственно

 

вот часть примера из моего кода

 

........

procedure TNetTransact.Reset;
begin
 FStream.Clear;
end;

var
 WSAData: TWSAData;

procedure Startup;
var
 ErrorCode: Integer;
begin
 ErrorCode := WSAStartup($0101, WSAData);
 if ErrorCode <> 0 then
   raise Exception.Create('WSAStartup');
end;

procedure Cleanup;
var
 ErrorCode: Integer;
begin
 ErrorCode := WSACleanup;
 if ErrorCode <> 0 then
   raise Exception.Create('WSACleanup');
end;

initialization
 Startup;

finalization
 Cleanup;
end.

 

прошу разработчиков внести эти важные коррективы .

 

И естественно выложить свежий релиз конфигуратора

спасибо )))

Ссылка на сообщение
Поделиться на других сайтах

Это проверено? По поводу WSACleanup?

Я так мыслю, что когда соединение ствится в очередь на listen на стороне инициатора происходит блокировка нити до того момента пока не установится соединение. Потом на клиентской стороне соединение успешно выполняется.

Ссылка на сообщение
Поделиться на других сайтах

WSACleanup() - функция завершает работу программы с библиотекой гнезд Ws2_32.dll.

 

всех гнезд в данном приложении

 

проверь у себя

 

Есть закономерность - жми обновление списка пользователей и пока он обновляется быстренько любому из них добавь некую сумму денег

 

и полезет то о чем писалось

 

потом перенеси nt.disconnect в правильно место и баг исчезнет

Ссылка на сообщение
Поделиться на других сайтах

Но ведь на клиентской стороне сокеты блокируемые! Он должен заблокироваться на коннекте до тех пор пока на сервере не освободится сокет.

Ссылка на сообщение
Поделиться на других сайтах

пардон - согласен,

 

сейчас исходников нету под рукой - но в connect-е поссмотри или вызывается WSACleanup и при каких обстоятельствах

 

в любом случаее это из за этого вызова - глянь

Ссылка на сообщение
Поделиться на других сайтах

Значит так запустил в режиме отладки

 

 

Обновляется список пользователей

 

в это время мы запускаем изменение параметров

 

затык происходит

 

на вызове

 

int NETTRANSACT::RxHeaderAnswer()

 

здесь мы начинаем принимать данные от сервера.

 

но пока мы до этого дошли

 

произошел где-то раньше nt.disconnect

 

который вызвал WSACleanup.

 

 

короче в классе NETTRANS нужно избавляться от WSACleanup

Ссылка на сообщение
Поделиться на других сайтах

хочу уточнить что затык происходит даже при попытке вызвать пользователя на редактирование именно в момент обновления списка

Ссылка на сообщение
Поделиться на других сайтах

сейчас опять нарвался и проконтролировал лог.

похоже что сначала, на повторном запросе при выполнении предыдущего, просто зависает конфигуратор.

в логах чисто, однако висит всерьёз и надолго.

а вот когда его пытаешся убить, то в логе и вываливается broken pipe.

по крайней мере в данный момент так было, хотя возможно что broken pipe просто вываливаются с задержкой.

 

А как выключить автоматическое обновление после вызова и закрытия окна редактирования пользователя? Оно ведь время занимает и мешает если вносить многим изменения. Всё же кнопка автообновления не зря придумана.

 

ИМНО надо просто конфигуратору с умом работать.

Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Вхід

Уже зарегистрированы? Войдите здесь.

Войти сейчас
  • Зараз на сторінці   0 користувачів

    Немає користувачів, що переглядають цю сторінку.

×
×
  • Створити нове...