@Override public synchronized void destroy() { LOG.debug("Destroy TCPListener Port: " + ipParameters.getPort()); // Close the serverSocket first to prevent new messages. try { if (serverSocket != null) serverSocket.close(); } catch (IOException e) { LOG.warn("Error closing socket" + e.getLocalizedMessage()); getExceptionHandler().receivedException(e); } // Close all open connections. if (handler != null) { handler.closeConnection(); } // Terminate Listener terminateListener(); initialized = false; LOG.debug("TCPListener destroyed, Port: " + ipParameters.getPort()); }
@Override public synchronized ModbusResponse sendImpl(ModbusRequest request) throws ModbusTransportException { if (!connected) { LOG.debug("No connection in Port: " + ipParameters.getPort()); throw new ModbusTransportException( new Exception("TCP Listener has no active connection!"), request.getSlaveId()); } if (!initialized) { LOG.debug("Listener already terminated " + ipParameters.getPort()); return null; } // Wrap the modbus request in a ip request. OutgoingRequestMessage ipRequest; if (ipParameters.isEncapsulated()) { ipRequest = new EncapMessageRequest(request); StringBuilder sb = new StringBuilder(); for (byte b : Arrays.copyOfRange(ipRequest.getMessageData(), 0, ipRequest.getMessageData().length)) { sb.append(String.format("%02X ", b)); } LOG.debug("Encap Request: " + sb.toString()); } else { ipRequest = new XaMessageRequest(request, getNextTransactionId()); StringBuilder sb = new StringBuilder(); for (byte b : Arrays.copyOfRange(ipRequest.getMessageData(), 0, ipRequest.getMessageData().length)) { sb.append(String.format("%02X ", b)); } LOG.debug("Xa Request: " + sb.toString()); } // Send the request to get the response. IpMessageResponse ipResponse; try { // Send data via handler! handler.conn.DEBUG = true; ipResponse = (IpMessageResponse) handler.conn.send(ipRequest); if (ipResponse == null) { throw new ModbusTransportException( new Exception("No valid response from slave!"), request.getSlaveId()); } StringBuilder sb = new StringBuilder(); for (byte b : Arrays.copyOfRange(ipResponse.getMessageData(), 0, ipResponse.getMessageData().length)) { sb.append(String.format("%02X ", b)); } LOG.debug("Response: " + sb.toString()); return ipResponse.getModbusResponse(); } catch (Exception e) { LOG.debug( e.getLocalizedMessage() + ", Port: " + ipParameters.getPort() + ", retries: " + retries); if (retries < 10 && !e.getLocalizedMessage().contains("Broken")) { retries++; } else { /* * To recover from a Broken Pipe, the only way is to restart serverSocket */ LOG.debug("Restarting Socket, Port: " + ipParameters.getPort() + ", retries: " + retries); // Close the serverSocket first to prevent new messages. try { if (serverSocket != null) serverSocket.close(); } catch (IOException e2) { LOG.debug("Error closing socket" + e2.getLocalizedMessage(), e); getExceptionHandler().receivedException(e2); } // Close all open connections. if (handler != null) { handler.closeConnection(); terminateListener(); } if (!initialized) { LOG.debug("Listener already terminated " + ipParameters.getPort()); return null; } executorService = Executors.newCachedThreadPool(); try { startListener(); } catch (Exception e2) { LOG.warn("Error trying to restart socket" + e2.getLocalizedMessage(), e); throw new ModbusTransportException(e2, request.getSlaveId()); } retries = 0; } LOG.warn( "Error sending request, Port: " + ipParameters.getPort() + ", msg: " + e.getMessage()); // Simple send error! throw new ModbusTransportException(e, request.getSlaveId()); } }