Выложите ВЕСЬ лог, хотя бы за 2-3 минуты. То, что ПЛК возвращает Reset - означает что он не может принять входящее, к примеру к нему УЖЕ по этому порту подключились. И соединение не разорвано клиентом, а он открывает ещё одно. Типичное, кстати, поведение для библиотек на PC, они предполагают что число сокетов у сервера бесконечное, а разъединение соединения - дело ОС, а там таймаут 2 часа по умолчанию![]()
Тролль-наседка, добрый, нежный и ласковый
проблемы нету, client.timeout ( ide сама подскажет, так же можно по пакету пошарить )
По умолчанию стоит
Timeout = 3
Проверил 1 и 10, разницы нету никакой.
Мне все же кажется, что косяк в контроллере, может что-то с чем-то конфликтовать или ресурсов не хватать?
Как я и говорил, для модбаса вообще не используется никаких библиотек, в целом в у меня кроме стандартных ничего нету в коде.
Последний раз редактировалось gOsToFf; 25.03.2020 в 15:00.
Что мне выкладывать? Весь проект, который есть или что? Сколько людей пишет на питоне, тем более которые есть тут в работе с ПЛК. Зато скриптики на питоне всем понятны, вот и взял БАЗОВЫЙ скрипт, как и писал в том сообщения где выкладывал и все. Какие дела? Мне рассказать как сеть устроена? Как траффик гуляет, где какие правила или что? Адреса разные, и находятся физически ПЛК в разных местах. Клиент на ГО я использую уже в более 20 разных проектах и везде все хорошо, а вот ПЛК и тем более ОВЕН сам использую в первый раз, потому и пришел за советом. У меня было скорее предположение, что косяк в либо в ПЛК, либо в ньюансах кодинга.
Я решил быкануть? Это вы делаете выводы, а не спрашиваете. Зачем убеждать человека ЗА меня, где есть косяк? Есть сомнение, можно спросить или подсказать.
Давайте подумаем, знаете ли вы, что если есть коллизия IP адресов в одном броадкаст домене, то роутеры блокируют такие пакеты на N секунд на момент перестроения arp таблиц, а следовательно будут потери пакетов, чуть выше я вам скинул скриншот с выборкой за 12 часов, где нету пропадания пакетов от слова совсем.
Когда проверка была на Python, была залита урезанная версия софта для на ПЛК для проверки если вдруг не хватает ресурсов. Там был slave1 в продуктиве 5. Проблема в том, что косяк соединения с ПЛК и тут не совсем это важно какой адрес слейва указан. Разница будет только в ответе. в одном случае придут данные, в другом будет ошибка некорректного пакета.
И всегда в обоих случаях сыпятся таймауты так же. Предложение добавить адрес было логичным, я проверил и его на всякий случай, хотя мало верил в успех.
В целом если уже говорить о моих ошибках, то там есть еще одна ошибка, а именно я пытался читать койлы с кодом 01, когда как мне нужны входные регистры. Опять же, ошибка будет в ответе, то есть я увижу ошибки протокола, а не таймаут.
Я же приложил скриншот с заббикса где проходит пинг до ПЛК. Сеть большая и контроллеры правда находятся в сегменте с 10м адресом не стандартным.
Если честно про дамп не совсем понял. Там есть первый пакет
ПК с которого я веду тест отправляет запрос SYN на открытие TCP сессию на ПЛК Овен, в ответ получает пакет RST, соотвественно стандартная настройка стека TCP пытается сделать повтор еще 2 раза, но так же получает RST после чего вываливается ошибка.
Сделать скриншот, что это реально ПЛК не проблема. Во вложении. Я вообще изначально хотел выложить целиком скриншот, но форум сказал, что я пытаюсь вложить слишком большой файл, вот и приходится их подрезать.
Жалусюь на оба, к сожалению косяк на обоих. Очень не хватает низкоуровнего дебага на ПЛК, чтобы разобрать проблему.
Кстати, банальный telnet на 502 порт так же не всегда отрабатывает ( просто зависает на соединении ), а иногда отрабатывает очеень долго и реже моментально. Именно просто на коннект. Так что не думаю, что есть смысл разбирать софт, который его опрашивает. Есть смысл разбираться в софте ПЛК наверно.
Выдержка из кода на GO если это реально так может помочь...
Код:const ( modbusPollingTimeout = 50 * time.Millisecond modbusFailRetryCount = 20 modbusHandlerTimeout = 3 * time.Second modbusHandlerIDLETimeout = 20 * time.Second modbusPLCSlaveId = 5 ) func NewTCPModbusHandler(ipAddress string) *modbus.TCPClientHandler { var modbusHandler *modbus.TCPClientHandler modbusHandler = modbus.NewTCPClientHandler(ipAddress) errConnect := modbusHandler.Connect() if errConnect != nil { //fmt.Println("ErrConnectModbusHandler to ", ipAddress, ": ", errConnect) } defer modbusHandler.Close() return modbusHandler } func ReadPLCConfiguration(segmentId int) PLCConfiguration { myHandler := NewTCPModbusHandler("10." + strconv.Itoa(segmentId) + ".10.5:502") myHandler.SlaveId = modbusPLCSlaveId myHandler.Timeout = modbusHandlerTimeout myHandler.IdleTimeout = modbusHandlerIDLETimeout client := modbus.NewClient(myHandler) var err error var readParam []byte count := 1 readParam, err = client.ReadInputRegisters(19, 15) for i := 0; i <= modbusFailRetryCount; i++ { if err != nil { count++ time.Sleep(modbusPollingTimeout) readParam, err = client.ReadInputRegisters(19, 15) } } fmt.Println("PLCConfig requests after ", count, " retries.") myHandler.Close() plcConf := PLCConfig[segmentId-1] if err == nil { s := reflect.ValueOf(&plcConf).Elem() for i := 0; i < s.NumField()-1; i++ { f := s.Field(i) var temp_byte []byte startIndex := 0 if i > 0 { startIndex = i * 2 } endIndex := startIndex + 1 temp_byte = append(temp_byte, readParam[startIndex]) temp_byte = append(temp_byte, readParam[endIndex]) temp_value := binary.BigEndian.Uint16(temp_byte) f.SetUint(uint64(temp_value)) } plcConf.LastUpdated = time.Now() } return plcConf }