-
[Socket] Ethernet to 485 communication개발/자바 2020. 9. 18. 18:17
package com.test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Client { private final static int BUFFER_SIZE = 1024; public static void main(String[] args) { try (Socket client = new Socket()){ InetSocketAddress address = new InetSocketAddress("dest ip", 9999); client.connect(address); try(OutputStream send = client.getOutputStream(); InputStream recv = client.getInputStream();) { System.out.println("client connected IP address:" + client.getRemoteSocketAddress().toString()); // receiving message thread pool ExecutorService receiver = Executors.newSingleThreadExecutor(); receiver.execute(() -> { try { while (true) { byte[] buffer = new byte[BUFFER_SIZE]; int len = recv.read(buffer, 0, BUFFER_SIZE); for (int i = 0; i < len; ++i) { System.out.printf("%02X ", buffer[i]); } System.out.println(); } } catch (Exception e) { e.printStackTrace(); } }); try(BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) { while(true) { String msg = reader.readLine(); if ("exit\r\n".equals(msg)) { break; } String[] data = msg.split(" "); int[] array = toIntArray(data); byte[] buffer = intArrayToByteArray(array); send.write(buffer); } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (IOException ioe) { // TODO Auto-generated catch block ioe.printStackTrace(); } } private static int[] toIntArray(String[] data) { int length = data.length; int[] array = new int[length]; for (int i = 0; i < length; ++i) { array[i] = Integer.parseInt(data[i], 16); } return array; } private static byte[] intArrayToByteArray(int[] intArray) { int length = intArray.length; byte[] byteArray = new byte[length]; for (int i = 0; i < length; ++i) { byteArray[i] = (byte)intArray[i]; } return byteArray; } }
자바는 c++과 다르게 서버용 소켓과 클라이언트용 소켓이 따로 있다. TCP와 485 포트의 통신은 컨버터가 필요하다. 테스트 환경은 ethernet-485 포트 컨버터, 485-pc 컨버터를 통해 ethernet과 pc가 연결되어 있다. 입력값은 Modbus 프로토콜을 따라야 하므로 워드(2바이트) 단위로 16진수로 맞춰 입력한다. slave에 정상적으로 프레임이 전달됐을 때의 응답 프레임은 콘솔에 출력해 값을 확인한다. 실제로는 CRC 값을 비교해 값의 유효성을 확인한다.
sLan 컨버터에 ip와 port값이 설정되어 있기 때문에 소켓을 이용해 해당 목적지로 연결한다. 데이터를 보내는 작업은 메인 스레드를 사용하고 데이터를 받는 작업은 스레드를 새로 생성한다. 입력값이 문자열이므로 이를 16진수로 변환해 정수형 배열에 담고 이를 다시 바이트 배열로 변환해 slave에 송신한다. 데이터를 받는 작업은 오직 하나의 스레드만 생성하도록 Executors.newSingleThreadExecutor()를 사용했다.
'개발 > 자바' 카테고리의 다른 글
[Intellij] 윈도우에서 한글 깨짐 해결 (0) 2023.05.08 [Regex] Pattern 객체를 이용해 효율적으로 replaceAll() 사용하기 (0) 2020.09.16 Dynamic Web Project를 Import한 후 생긴 오류들 (0) 2020.04.25 추상 클래스는 무엇 (0) 2020.03.19 참조변수에 대한 작은 오해 (0) 2020.03.16