boneskos Posted January 9, 2013 Share Posted January 9, 2013 Здравствуйте! Очень необходим стабильный код программы проброски трафика тсп-порта в ком порт IA240 под UNIX. Во вложении рабочий вариант (исходник, конф-файл и скомпилированный файл). При длительной работе этого варианта периодически образуются нерабочие окна минут в 20-40.... При прочих модификациях наблюдались полные зависания приложения . Прошу помощи у специалистов! Пожалуйста, укажите ошибку или поделитесь стабильным рабочим кодом проброски трафика. Готов проспонировать 300-500 рублей на пиво при условии стаблильной работы вашего кода более суток. Условия обмена по трафику: 1. Запросы сверху-вниз. Т.е. открывается ТСП-сокет, из него приходит запрос и транслируется в порт. Из порта должен прийти ответ в течении 1-4 сек. макисмум и отправлен обратно в tcp-порт. (Если не пришел, то ждать ответа дольше смысла нет). 2. Если, одновременно с открытым сокетом открывается второй, то желательно, чтобы последний был главным и обмен в ком-порт переводился на него. ( в приложенном файле - напротив, первый открытый сокет захватывает порт и отключается только по таймауту (впринципе, таймаут - это уже попытки стабилизировать полные зависания...)). 3. Пакеты по обмену небольшие. В большинстве случаев укладываются в 255 - 300 байт. Жду с нетерпением любой помощи. Заранее благодарю за советы. АТК-tcp2ComIA240.zip Link to comment
Komantsev Posted January 9, 2013 Share Posted January 9, 2013 Здравствуйте! Я, к сожалению, не силен проверять коды, но хочу просто обратить внимание на грамотные примеры программ, расположенные на подсайте rcorecommunity.moxa.com. Есть пример простейшего TCP-сервера, есть пример работы с COM-портом. Может быть, просто попробовать их объединить, и получится всё здорово? Link to comment
boneskos Posted January 10, 2013 Author Share Posted January 10, 2013 Здравствуйте! Спасибо за ссылку. Но похоже это тоже самое что и на диске в комплекте с моксой.... Дело в том, что с этого все начиналось... Стандартные примеры очень похожи, но не подходят. Например, в одном из примеров направление связи из ком в тсп порт - по инициативе из ком-порта... Я тоже вначале думал, что достаточно изменить пару строк и скомплировать. Я работал с внешним программистом который уже не один год кодит под моксу, он мне составил код из предыдущего топика. Но испытания показали, что он не стабильно работает. Стабилизировать его у него не получается. Предыдущие попытки и навороты приводили к зависанию приложения через некоторое время работы. Вот и прошу помощи у спецов в такой простой задаче. Блин. Помогите, программисты. Если вопрос на столько сложен, что требует оплаты, пишите свои пожелания на web2reg[cобака]ya.ru. Вообще, считаю, что такой функционал должен быть достоянием общественности и подготовлен спецами Моксы... Заранее благодарю за ответ. Link to comment
boris_r_v Posted January 17, 2013 Share Posted January 17, 2013 Насчет достояния общественности - очень спорный вопрос. Код поглядел. причину предполагаю - скажите вам использования TCP протокола принципиально или его можно на UDP заменить. Ибо причина подвисаний скорее всего в таймаутах на закрытие и открытие соединений по TCP, а в этой прожке при любом сбое на чтение или запись портов serial & lan происходит закрытие всех портов и потом по новой открываются. Вариантов два: 1. менять TCP на UDP 2. продумать какая нужна реакция на ошибки чтения/записи - я бы оба варианта применил. P.S. или вообще pipe использовать.... Link to comment
boris_r_v Posted January 17, 2013 Share Posted January 17, 2013 Еще мысль возникла. Если у Вас это единичный экземпляр то ладно. Но если это тиражируемое решение по организации обмена с цифровыми устройствами, - то Вы используете не те решения. Необходимый вам функционал реализуют NPortы, они открывают TCP-порты, которые ассоциируются с serial портами и гоняют между ними трафик. Т.е. драйвера которые дают com-порты в винде ставить не обязательно, ибо драйвера только открывают TCP соединения, и пропускают трафик через себя. Понятно, что NPort по сути это Plug&Play устройства не требующего никакого стороннего софта, а только настройку режимов работы через web-морду. Если все же нужен именно встраиваемый контроллер то пишите в личку, чего надо с софтинкой помогу. Link to comment
Komantsev Posted January 17, 2013 Share Posted January 17, 2013 Борис, Спасибо Вам за компетентные комментарии!!! Link to comment
lysenkov Posted February 4, 2013 Share Posted February 4, 2013 boneskos, не знаю, насколько сильно помогу, но по моему опыту работы с COM-портами (под виндой пока), как раз с RS-485 2 wire, одиночного чтения из порта не достаточно. Иногда, функция чтения из порта не выдает весь кусок данных, который туда пришел/идет. Читать из порта нужно до тех пор, пока не придет необходимый объем данных или не наступит таймаут. В вашем же примере, чтение производится один раз, затем в следующем цикле снова идет запись, при этом где гарантия, что все данные от устройства выбрались чтением? В недуплексном канале обмена, коим является RS-485, записью в порт вы заставляете порт переключиться в режим передачи, а это может оказаться еще рано, возможно он еще принимает данные. И еще: Вы вызываете функцию чтения из сом-порта сразу после записи, при этом flow control у вас отключен. В этом случае, на мой взляд, функцию чтения можно вызывать только по прошествию паузы, достаточной для отправки Вашего объема данных через сом-порт на данной скорости или после проверки того факта, что буфер передачи опустошился (не подскажу как сделать это в линуксе). Link to comment
oiv_1968 Posted January 27, 2016 Share Posted January 27, 2016 Здравствуйте! Очень необходим стабильный код программы проброски трафика тсп-порта в ком порт IA240 под UNIX. Во вложении рабочий вариант (исходник, конф-файл и скомпилированный файл). При длительной работе этого варианта периодически образуются нерабочие окна минут в 20-40.... При прочих модификациях наблюдались полные зависания приложения . Прошу помощи у специалистов! Пожалуйста, укажите ошибку или поделитесь стабильным рабочим кодом проброски трафика. Готов проспонировать 300-500 рублей на пиво при условии стаблильной работы вашего кода более суток. Условия обмена по трафику: 1. Запросы сверху-вниз. Т.е. открывается ТСП-сокет, из него приходит запрос и транслируется в порт. Из порта должен прийти ответ в течении 1-4 сек. макисмум и отправлен обратно в tcp-порт. (Если не пришел, то ждать ответа дольше смысла нет). 2. Если, одновременно с открытым сокетом открывается второй, то желательно, чтобы последний был главным и обмен в ком-порт переводился на него. ( в приложенном файле - напротив, первый открытый сокет захватывает порт и отключается только по таймауту (впринципе, таймаут - это уже попытки стабилизировать полные зависания...)). 3. Пакеты по обмену небольшие. В большинстве случаев укладываются в 255 - 300 байт. Жду с нетерпением любой помощи. Заранее благодарю за советы. Простите, но я не увидел в приложеннм коде формирования второго потока для работы со вторым соединением по TCP. int do_it() { char *ip; int size, rz, len; struct sockaddr_in client; struct timeval twait; fd_set ListenSockets; size = sizeof(client); while(1) { printf("accept...\n"); sClient = accept(sListen, (struct sockaddr *)&client, &size); if (sClient < 0){ print_err_mess("accept...failed"); break; } ip = inet_ntoa(client.sin_addr); if (!ip) continue; sprintf(&sbuf[0], "connect from %s", ip); print_mess(&sbuf[0]); endtime_session = time(NULL) + cfg.max_time_session_min * 60; // set socket to nonblock rz = fcntl(sClient, F_GETFL); rz |= O_NONBLOCK; if (fcntl(sClient, F_SETFL, rz) < 0) { print_err_mess("set socket to nonblock fail"); break; } while(1) { if (time(NULL) > endtime_session) { print_mess("session end time"); return 2; } FD_ZERO(&ListenSockets); FD_SET(sClient, &ListenSockets); twait.tv_sec = 0; twait.tv_usec = 100; rz = select(sClient+1, &ListenSockets, NULL, NULL, &twait); if (rz < 0) { close_fd(&sClient); break; } else if (!rz || !FD_ISSET(sClient, &ListenSockets)) { //nothing receive } else { // receive data form LAN rz = recv(sClient, rbuf, BUFFER_LEN, 0); if (!rz){ printf("LAN: recvice 0 bytes (!)\n"); close_fd(&sClient); break; } else if (rz < 0) { if (errno == EAGAIN) { /* The socket is marked non-blocking, and the receive operation would block, or a receive timeout had been set, and the timeout expired before data were received. */ continue; } if (errno == ENOTCONN) { /* The socket is associated with a connection-oriented protocol and has not been connected */ close_fd(&sClient); break; } close_fd(&sClient); print_mess("LAN disconnected"); printf("\n"); break; } if (cfg.log) { if (cfg.log == 2) printf("LAN: read %d bytes\n", rz); if (cfg.log > 2) PrintBytes(rbuf, rz); } // write data to serial port len = write(fd, rbuf, rz); if (len < 0) { print_err_mess("COM: write fail"); return -1; } } // read data from serial port len = read(fd, sbuf, BUFFER_LEN); if (len < 0) { print_err_mess("COM: read data fail"); return -1; } else if (len > 0) { if (cfg.log) { if (cfg.log == 2) printf("COM: read %d bytes\n", len); if (cfg.log > 2) PrintBytes(sbuf, len); } // send data to LAN rz = send(sClient, sbuf, len, 0); if(rz < 0){ print_err_mess("LAN: send data fail"); return -1; } } } } return 0; } Так, что обрабатывать второй сокет некому! Так что после приёма соединения необходимо открывать "параллельный" поток для обработки текущего соединения для sClient = accept(sListen, (struct sockaddr *)&client, &size); , а этот цикл адаптировать для ожидания другого sClient = accept(sListen, (struct sockaddr *)&client, &size); далее для которого будет открыт свой поток. Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now