TCPServer.java 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. package tcpunit;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.io.PrintWriter;
  5. import java.net.InetSocketAddress;
  6. import java.net.ServerSocket;
  7. import java.net.Socket;
  8. import java.util.HashMap;
  9. import java.util.Set;
  10. public class TCPServer {
  11. private final String hostAddress; // 服务器地址
  12. private final int myPort; // 服务器端口号
  13. private ServerSocket myServerSocket; // 服务器ServerSocket
  14. private Thread myThread; // 服务器线程
  15. private OnRequestListener requestListener; // 数据请求监听器
  16. private OnResponseListener responseListener; // 数据响应监听
  17. private OnSocketChange socketChangeListener; // 客户端状态改变监听器
  18. private ClientRunner clientRunner; // 客户端处理线程
  19. private Parser parser = new Parser();
  20. private HashMap<Integer, Socket> clients = new HashMap<>(); // 在线客户端列表<客户端编号,客户端对象>
  21. public TCPServer(int port) {
  22. this(null, port);
  23. }
  24. public TCPServer(String hostAddress, int port) {
  25. this.hostAddress = hostAddress;
  26. this.myPort = port;
  27. clientRunner = new ClientRunner();
  28. }
  29. /**
  30. * 安全关闭ServerSocket
  31. *
  32. * @param serverSocket
  33. */
  34. private static final void safeClose(ServerSocket serverSocket) {
  35. if (serverSocket != null) {
  36. try {
  37. serverSocket.close();
  38. } catch (IOException e) {
  39. }
  40. }
  41. }
  42. /**
  43. * 安全关闭Socket
  44. *
  45. * @param socket
  46. */
  47. private static final void safeClose(Socket socket) {
  48. if (socket != null) {
  49. try {
  50. socket.close();
  51. } catch (IOException e) {
  52. }
  53. }
  54. }
  55. /**
  56. * 安全关闭BufferedReader
  57. *
  58. * @param is
  59. */
  60. private static void safeClose(InputStream is) {
  61. if (is != null) {
  62. try {
  63. is.close();
  64. } catch (IOException ignored) {
  65. }
  66. }
  67. }
  68. /**
  69. * 安全关闭PrintWriter
  70. *
  71. * @param writer
  72. */
  73. private static final void safeClose(PrintWriter writer) {
  74. writer.close();
  75. }
  76. /**
  77. * 开始TCP服务
  78. */
  79. public void start() {
  80. try {
  81. myServerSocket = new ServerSocket();
  82. myServerSocket.bind((hostAddress != null) ? new InetSocketAddress(hostAddress, myPort) : new InetSocketAddress(myPort));
  83. } catch (IOException e) {
  84. System.out.println("Port is occupied");
  85. }
  86. myThread = new Thread(new Runnable() {
  87. int disConnectCount=0;
  88. char resData;
  89. @Override
  90. public void run() {
  91. do try {
  92. final Socket finalAccept = myServerSocket.accept(); // 监听客户端连接
  93. clientRunner.exec(() -> {
  94. InputStream inputStream = null;
  95. try {
  96. inputStream = finalAccept.getInputStream();
  97. String packet = null;
  98. disConnectCount = 0;
  99. while (!finalAccept.isClosed()) {
  100. do {
  101. resData = (char) inputStream.read();
  102. if (resData == 65535) {
  103. disConnectCount++;
  104. if (disConnectCount > 3) {
  105. System.out.println("Connection is disconnected");
  106. throw new IOException();
  107. }
  108. } else {
  109. disConnectCount = 0;
  110. }
  111. packet = parser.message_parse_char(resData);
  112. } while (packet == null);
  113. responseListener.onResponseListener(packet);
  114. //System.out.println(packet);
  115. }
  116. } catch (IOException e) {
  117. e.printStackTrace();
  118. System.out.println("Device offline");
  119. safeClose(inputStream);
  120. safeClose(finalAccept);
  121. removeSocket(clientRunner.id);
  122. }
  123. });
  124. } catch (IOException e) {
  125. e.printStackTrace();
  126. } while (!myServerSocket.isClosed());
  127. }
  128. });
  129. myThread.setDaemon(true);
  130. myThread.setName("TcpServer Main Listener");
  131. myThread.start();
  132. }
  133. private boolean isConnected(Socket socket) {
  134. try {
  135. socket.sendUrgentData(0xff);
  136. return true;
  137. } catch (IOException e) {
  138. e.printStackTrace();
  139. return false;
  140. }
  141. }
  142. private synchronized void removeSocket(int id) {
  143. clients.remove(id);
  144. }
  145. /**
  146. * 停止TCP服务
  147. */
  148. public void stop() {
  149. try {
  150. safeClose(myServerSocket);
  151. if (myThread != null) {
  152. myThread.join();
  153. }
  154. } catch (Exception e) {
  155. e.printStackTrace();
  156. }
  157. }
  158. /**
  159. * 监听服务异常结束
  160. */
  161. public void waitServerStop() {
  162. try {
  163. myThread.join();
  164. } catch (InterruptedException e) {
  165. e.printStackTrace();
  166. }
  167. }
  168. /**
  169. * 客户端处理线程
  170. */
  171. public static class ClientRunner {
  172. private long requestCount;
  173. public int id;
  174. public void exec(Runnable code) {
  175. ++requestCount;
  176. Thread t = new Thread(code);
  177. t.setDaemon(true);
  178. t.setName("TcpServer thread (#" + requestCount + ")");
  179. t.start();
  180. }
  181. }
  182. /**
  183. * 监听客户端请求,并可以修改请求内容
  184. */
  185. public interface OnRequestListener {
  186. String onRequestListener(String request);
  187. }
  188. /**
  189. * 设置客户端请求监听器
  190. *
  191. * @param listener
  192. */
  193. public void setOnRequestListener(OnRequestListener listener) {
  194. this.requestListener = listener;
  195. }
  196. /**
  197. * 监听网关响应数据,并可以修改请求内容
  198. */
  199. public interface OnResponseListener {
  200. String onResponseListener(String response);
  201. }
  202. /**
  203. * 设置网关响应监听器
  204. *
  205. * @param listener
  206. */
  207. public void setOnResponseListener(OnResponseListener listener) {
  208. this.responseListener = listener;
  209. }
  210. public interface OnSocketChange {
  211. void onSocketChange(Set<String> hostAddress);
  212. }
  213. public void setOnSocketChange(OnSocketChange listener) {
  214. this.socketChangeListener = listener;
  215. }
  216. }