fredik Опубликовано: 12 червня, 2007 Опубликовано: 12 червня, 2007 подскажите что такое, и как его лечить (строка 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!
p0int Опубліковано: 12 червня, 2007 Опубліковано: 12 червня, 2007 такое бывает редко просто перегружаю биллинг и все
fredik Опубліковано: 13 червня, 2007 Автор Опубліковано: 13 червня, 2007 такое бывает редкопросто перегружаю биллинг и все да но при етом слитает билинг что не очень приятно....
vop Опубліковано: 13 червня, 2007 Опубліковано: 13 червня, 2007 подскажите что такое, и как его лечить Это попытка записи в закрытый сокет. Лечится только при написании кода.
fredik Опубліковано: 13 червня, 2007 Автор Опубліковано: 13 червня, 2007 Лечится только при написании кода. написании какого кода и если есть подилитесь, люди добые
napTu Опубліковано: 5 грудня, 2007 Опубліковано: 5 грудня, 2007 короче ситуация такая: захожу в кофигуратор правлю юзера сохраняю обновляю во время обновления пытаюсь снова открыть юзера конфигуратор зависает в логе стг обнаруживается множество broken pipe что интересно, проблемы была как на версии 2.0, так и на 2.403b сейчас.(bsd410)
madf Опубліковано: 5 грудня, 2007 Опубліковано: 5 грудня, 2007 В последних версиях (Новая сборка СТГ 2.4) этого уже не должно быть.
napTu Опубліковано: 5 грудня, 2007 Опубліковано: 5 грудня, 2007 судя по теме, там устраняется баг с фаерфоксом, а у меня текстовая БД. Боязно накатывать последнюю бетту. Кто нить может точно сказать про эту проблему?
madf Опубліковано: 5 грудня, 2007 Опубліковано: 5 грудня, 2007 судя по теме, там устраняется баг с фаерфоксом, а у меня текстовая БД. Боязно накатывать последнюю бетту. Кто нить может точно сказать про эту проблему? Этот баг точно проявлялся при работе с firebird. В остальных случаях он был или очень редкий или совсем не проявлялся. Непосредственно с firebird он никак не связан, а связан с логирование работы сервера. Можете просто закоментировать код функции printfd в файле common.cpp библиотеки common.lib и пересобрать проект (если у вас stg с динамическими библиотеками - пересобрать библиотеку и положить ее вместо старой). Это должно помочь.
Genius Опубліковано: 5 грудня, 2007 Опубліковано: 5 грудня, 2007 Баг одновременных запросов к сокету конфигуратора, в том числе и из одного конфигуратора у меня наблюдается даже на последней бете с аналогичными симптомами.
vovksextra Опубліковано: 5 грудня, 2007 Опубліковано: 5 грудня, 2007 совершенно верно )) или просто кто-то долбит порт )) http://local.com.ua/forum/index.php?showtopic=9757&st=135
Genius Опубліковано: 5 грудня, 2007 Опубліковано: 5 грудня, 2007 Ну, в данном случае это просто параллельные коннекты кассиров, по дебагу я слежу за такими вещами, но вообще надо как то распараллелить систему работы конфигураторов, потому что кассирам это иногда сильно мешает.
madf Опубліковано: 6 грудня, 2007 Опубліковано: 6 грудня, 2007 Стоп-стоп! Конфигуратор работает по 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.
Genius Опубліковано: 6 грудня, 2007 Опубліковано: 6 грудня, 2007 Да, в очередь он устанавливается, но при большом числе пользователей, обновление списка достаточно длительный процесс (~20-30 сек) и конфигуратор на это время подвисает, часто намертво и приходиться его убивать после чего плодятся Broken pipe. И второй вариант при обновлении списка пользователей отредактировать какого-нибудь пользователя, что вызовет похожие косяки в конфигураторе из-за слишком длительного периода ожидания. Думаю правильнее переписать систему на параллельную обработку запросов конфигураторов.
vovksextra Опубліковано: 6 грудня, 2007 Опубліковано: 6 грудня, 2007 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) должно помочь сегодня ночью перекомпилим - завтра скажу
vovksextra Опубліковано: 6 грудня, 2007 Опубліковано: 6 грудня, 2007 баг найден - готовлю методику исправления. Дело не в listen - он и правду не причем
vovksextra Опубліковано: 6 грудня, 2007 Опубліковано: 6 грудня, 2007 первое что мы делали пробывали держать открытый сокет и в конфигураторе запустить обновление.процедура обновления "висит",но при освобождении сокета корректно продолжает обновлять список. То-есть запросы на сокет стоят в ожидании и выполняются при достижении своей очереди так как в серверной части используется работа с сокетами в режиме "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. прошу разработчиков внести эти важные коррективы . И естественно выложить свежий релиз конфигуратора спасибо )))
madf Опубліковано: 6 грудня, 2007 Опубліковано: 6 грудня, 2007 Это проверено? По поводу WSACleanup? Я так мыслю, что когда соединение ствится в очередь на listen на стороне инициатора происходит блокировка нити до того момента пока не установится соединение. Потом на клиентской стороне соединение успешно выполняется.
vovksextra Опубліковано: 6 грудня, 2007 Опубліковано: 6 грудня, 2007 WSACleanup() - функция завершает работу программы с библиотекой гнезд Ws2_32.dll. всех гнезд в данном приложении проверь у себя Есть закономерность - жми обновление списка пользователей и пока он обновляется быстренько любому из них добавь некую сумму денег и полезет то о чем писалось потом перенеси nt.disconnect в правильно место и баг исчезнет
madf Опубліковано: 6 грудня, 2007 Опубліковано: 6 грудня, 2007 Но ведь на клиентской стороне сокеты блокируемые! Он должен заблокироваться на коннекте до тех пор пока на сервере не освободится сокет.
vovksextra Опубліковано: 6 грудня, 2007 Опубліковано: 6 грудня, 2007 пардон - согласен, сейчас исходников нету под рукой - но в connect-е поссмотри или вызывается WSACleanup и при каких обстоятельствах в любом случаее это из за этого вызова - глянь
vovksextra Опубліковано: 6 грудня, 2007 Опубліковано: 6 грудня, 2007 Значит так запустил в режиме отладки Обновляется список пользователей в это время мы запускаем изменение параметров затык происходит на вызове int NETTRANSACT::RxHeaderAnswer() здесь мы начинаем принимать данные от сервера. но пока мы до этого дошли произошел где-то раньше nt.disconnect который вызвал WSACleanup. короче в классе NETTRANS нужно избавляться от WSACleanup
napTu Опубліковано: 6 грудня, 2007 Опубліковано: 6 грудня, 2007 хочу уточнить что затык происходит даже при попытке вызвать пользователя на редактирование именно в момент обновления списка
vovksextra Опубліковано: 7 грудня, 2007 Опубліковано: 7 грудня, 2007 Убрал я все вызовы WSACleanup из всех методов класса NETTrans - "затык" остался ((((( значит где-то в другом месте нужно рыть (((
napTu Опубліковано: 11 грудня, 2007 Опубліковано: 11 грудня, 2007 сейчас опять нарвался и проконтролировал лог. похоже что сначала, на повторном запросе при выполнении предыдущего, просто зависает конфигуратор. в логах чисто, однако висит всерьёз и надолго. а вот когда его пытаешся убить, то в логе и вываливается broken pipe. по крайней мере в данный момент так было, хотя возможно что broken pipe просто вываливаются с задержкой. А как выключить автоматическое обновление после вызова и закрытия окна редактирования пользователя? Оно ведь время занимает и мешает если вносить многим изменения. Всё же кнопка автообновления не зря придумана. ИМНО надо просто конфигуратору с умом работать.
Рекомендованные сообщения
Создайте аккаунт или войдите в него для комментирования
Вы должны быть пользователем, чтобы оставить комментарий
Создать аккаунт
Зарегистрируйтесь для получения аккаунта. Это просто!
Зарегистрировать аккаунтВхід
Уже зарегистрированы? Войдите здесь.
Войти сейчас