SSLClient.java 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. package com.icontrols.kakao.socket.utils;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.io.InputStreamReader;
  6. import java.io.OutputStream;
  7. import java.io.OutputStreamWriter;
  8. import java.io.PrintWriter;
  9. import java.net.ConnectException;
  10. import java.net.InetAddress;
  11. import java.net.InetSocketAddress;
  12. import java.net.Socket;
  13. import java.net.SocketAddress;
  14. import java.net.SocketTimeoutException;
  15. import java.security.cert.X509Certificate;
  16. import javax.net.ssl.SSLContext;
  17. import javax.net.ssl.SSLSocketFactory;
  18. import javax.net.ssl.TrustManager;
  19. import javax.net.ssl.X509TrustManager;
  20. import org.slf4j.Logger;
  21. import org.slf4j.LoggerFactory;
  22. /**
  23. * @description SSL Client 용 소켓 생성을 지원하는 api 이다.
  24. *
  25. * @import kr.co.icontrols.sslapi.SslClient
  26. */
  27. public class SSLClient {
  28. private static final Logger logger = LoggerFactory.getLogger(SSLClient.class);
  29. private Socket sslSocket = null;
  30. private byte[] ServerIP = null;
  31. /**
  32. * SSL 암호화된 Socket 을 생성한다. (client 전용)
  33. *
  34. * @param host - 소켓에 연결되어야 하는 호스트 주소
  35. * @param port - 소켓이 접속되고있는 호스트의 포트 번호
  36. *
  37. * <br>
  38. * <br>
  39. * @Example
  40. *
  41. * <pre class="prettyprint">
  42. * // SslClient 정의
  43. * SslClient sslClientSocket = new SslClient("10.0.1.1", 10000);
  44. * // Socket 가져오기
  45. * Socket socket = sslClientSocket.getSocket();
  46. * </pre>
  47. */
  48. public SSLClient(String host, int port) {
  49. // 1. Param Check
  50. if (host == null) {
  51. logger.info("[SSLClient] Param 'host' is null !!!");
  52. return;
  53. }
  54. // 2. IP Convert & Check
  55. byte[] retIP = IPConverting(host);
  56. if (retIP == null) {
  57. logger.info("[SSLClient] IPConverting Error !!!");
  58. return;
  59. }
  60. ServerIP = retIP;
  61. // 3. TLS Socket Make
  62. try {
  63. SSLContext context = SSLContext.getInstance("TLS");
  64. context.init(null, trustAllCerts, null);
  65. SSLSocketFactory sf = context.getSocketFactory();
  66. // [2018-02-08]
  67. // * 서버에 DNS Server (bind9)를 설치하여 문제는 해결하였으나, 불필요한 DNS Lookup을 막고자
  68. // 호스트네임이 정의된 InetAddress 로 IP를 부여함.
  69. // DNS Lookup 이 일어나지 않게 하기 위하여 호스트네임이 정의된 InetAddress 로 주소를 부여함.
  70. // IP 만을 "10.0.1.1" 이런 형태로 부여할 경우 Cache 에 접속정보가 없을경우 DNS Lookup이 일어나게되며,
  71. // DNS Server 가 없을 경우 지연현상이 발생됨.
  72. logger.info("--> server IP = " + ServerIP);
  73. InetAddress mInetAddress = InetAddress.getByAddress("", ServerIP);
  74. logger.info("-->ip address -- " + mInetAddress + " -- " + port);
  75. sslSocket = sf.createSocket(mInetAddress, port);
  76. } catch (Exception e) {
  77. logger.info("[SSLClient] TLS Socket Make Exception Error");
  78. e.printStackTrace();
  79. }
  80. }
  81. /**
  82. * 생성된 SSL Socket 을 반환한다.
  83. *
  84. * @return (Socket) sslSocket
  85. */
  86. public Socket getSocket() {
  87. return sslSocket;
  88. }
  89. /**
  90. * 신뢰할 수 있는 인증기관의 공개키 인지 검증하는 코드를 사용자 코드로 대체 아무런 동작을 하지 않으며 모든 서버 연결을 신뢰한다는
  91. * 의미이다.
  92. */
  93. private TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
  94. public X509Certificate[] getAcceptedIssuers() {
  95. X509Certificate[] myTrustedAnchors = new X509Certificate[0];
  96. return myTrustedAnchors;
  97. }
  98. @Override
  99. public void checkClientTrusted(X509Certificate[] certs, String authType) {
  100. }
  101. @Override
  102. public void checkServerTrusted(X509Certificate[] certs, String authType) {
  103. }
  104. } };
  105. /**
  106. * String IP 를 Byte [] IP 로 변환한다.
  107. *
  108. * @param inIP - (String) input IP
  109. *
  110. * @return (byte []) output IP
  111. */
  112. private byte[] IPConverting(String inIP) {
  113. // 1. Param Check
  114. if (inIP == null)
  115. return null;
  116. // 2. Convert
  117. char[] CharArray = inIP.toCharArray();
  118. if (CharArray == null)
  119. return null;
  120. for (int i = 0; i < CharArray.length; i++)
  121. if (CharArray[i] == '.')
  122. CharArray[i] = ';';
  123. String newIP = new String(CharArray);
  124. String[] splitData = newIP.split(";");
  125. if (splitData == null)
  126. return null;
  127. if (splitData.length != 4)
  128. return null;
  129. byte[] outIParray = new byte[4];
  130. for (int i = 0; i < splitData.length; i++)
  131. outIParray[i] = (byte) Integer.parseInt(splitData[i]);
  132. // 3. return
  133. return outIParray;
  134. }
  135. public static String sendToWallpad(String ip, String xml) {
  136. int port = 10000; // 접속할 port - 월 패드/단지서버 포트번호
  137. Socket requestSock = null;
  138. SocketAddress socketAddress = new InetSocketAddress(ip, port); // 접속할
  139. BufferedReader br = null;
  140. InputStream is = null;
  141. OutputStream os = null;
  142. PrintWriter pw = null;
  143. String sendMsg = null; // 보내는 메시지
  144. String recvMsg = ""; // 받는 메시지
  145. StringBuilder sb = new StringBuilder();
  146. try {
  147. port += 1000;
  148. SSLClient sslClientSocket = new SSLClient(ip, port);
  149. requestSock = sslClientSocket.getSocket();
  150. sendMsg = xml; // 요청 xml
  151. os = requestSock.getOutputStream();
  152. is = requestSock.getInputStream();
  153. pw = new PrintWriter(new OutputStreamWriter(os)); // 입력한 문자 전송
  154. // br = new BufferedReader(new InputStreamReader(is));
  155. pw.println(sendMsg); // sendMsg출력
  156. pw.flush(); // 버퍼메모리 사용
  157. // light request를 보내서 reply 수신&출력.
  158. // String line = null;
  159. // while ((line = br.readLine()) != null) {
  160. // logger.info("line = " + line);
  161. // sb.append(line);
  162. //
  163. // // </imap>을 받는데 딜레이 생겨서 안받음.... readline()의 문제? *********
  164. // if (line.equals(" </service>")) {
  165. // // System.out.println("service same~~~");
  166. // break;
  167. // }
  168. // }
  169. // recvMsg = sb.toString();
  170. // // System.out.println("recvMsg1 = " + recvMsg);
  171. // if (recvMsg.length() != 0) {
  172. // recvMsg += "</imap>"; // service에서 멈추기 때문에 마지막 XML 구문을 닫아줘야 함.
  173. // }
  174. // // System.out.println("recvMsg2 = " + recvMsg);
  175. //
  176. pw.close();
  177. // br.close();
  178. requestSock.close();
  179. } catch (ConnectException ce) {
  180. // TODO Auto-generated catch block
  181. recvMsg = "ConnectionException";
  182. logger.info("[sendToWallpad] - Exception !!! ~~~");
  183. try {
  184. Thread.sleep(2000);
  185. } catch (InterruptedException e) {
  186. // TODO Auto-generated catch block
  187. e.printStackTrace();
  188. }
  189. ce.printStackTrace();
  190. } catch (SocketTimeoutException se) {
  191. // TODO Auto-generated catch block
  192. recvMsg = "SocketTimeoutException";
  193. logger.info("connection TIME OUT!!!");
  194. try {
  195. Thread.sleep(100);
  196. } catch (InterruptedException e) {
  197. // TODO Auto-generated catch block
  198. e.printStackTrace();
  199. }
  200. } catch (IOException ioe) {
  201. // TODO Auto-generated catch block
  202. recvMsg = "IOException";
  203. ioe.printStackTrace();
  204. }
  205. // System.out.println("return recvMsg = " + recvMsg);
  206. // logger.info("recv = " + recvMsg);
  207. return recvMsg;
  208. }
  209. }