1 Java Socket簡介
所謂socket 通常也稱作”套接字“,用于描述IP地址和端口,是一個通信鏈的句柄。應用程序通常通過”套接字”向網絡發出請求或者應答網絡請求。Socket和ServerSocket類庫位于Java.NET包中。ServerSocket用于服務器端,Socket是建立網絡連接時使用的。在連接成功時,應用程序兩端都會產生一個Socket實例,操作這個實例,完成所需的會話。對于一個網絡連接來說,套接字是平等的,并沒有差別,不因為在服務器端或在客戶端而產生不同級別。
2 TCPServer代碼實例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
|
import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.Date; import java.util.HashMap; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * TCP服務器端,單例模式 * @author xiang * */ public class TCPServer implements Runnable { private static final Logger logger = LoggerFactory.getLogger(TCPServer. class ); //成員變量/ private static TCPServer serverInstance; private static Map<String, SocketThread> socketMaps = new HashMap<String,SocketThread>(); //每個客戶端連接時都會新建一個SocketThread與之對應 private static ServerSocket serverSocket; //服務器套接字 private static int serPort = 9999 ; //服務器端口號 private static boolean flag; //服務器狀態標志 private static final int BUFFER_SIZE = 512 ; //數據接收字符數組大小 //構造函數/ private TCPServer() { } /** * 獲取實例 * @return TCPServer實例serverInstance */ public static TCPServer getServerInstance(){ if (serverInstance== null ) serverInstance = new TCPServer(); return serverInstance; } /** * 開啟服務器 * @throws IOException */ public void openTCPServer() throws IOException{ if (serverSocket== null || serverSocket.isClosed()){ serverSocket = new ServerSocket(serPort); flag = true ; } } /** * 關閉服務器 * @throws IOException */ public void closeTCPServer() throws IOException{ flag = false ; if (serverSocket!= null ) serverSocket.close(); /*for (Map.Entry<String, SocketThread> entry : socketMaps.entrySet()) { System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue()); } */ for (SocketThread value : socketMaps.values()) value.closeConnect(); socketMaps.clear(); } /** * 服務器向客戶端發送數據 * @param bytes[]:待發送的字符數組 * @param key 客戶端的key,為空或""時表示數據群發 * @throws IOException */ public void sendMessage(String key,byte[] msgBytes){ if(key==null||key.equals("")){ for (SocketThread value : socketMaps.values()) value.sendMassage(msgBytes); }else{ SocketThread thread = socketMaps.get(key); if(thread!=null) thread.sendMassage(msgBytes); } } /** * 服務器向客戶端發送數據 * @param key 客戶端的key,為空或""時表示數據群發 * @param msgStr:待發送的字符串 * @throws IOException */ public void sendMessage(String key,String msgStr){ byte[] sendByte = msgStr.getBytes(); if(key==null||key.equals("")){ for (SocketThread value : socketMaps.values()) value.sendMassage(sendByte); }else{ SocketThread thread = socketMaps.get(key); if(thread!=null) thread.sendMassage(sendByte); } } @Override public void run() { logger.info("服務器線程已經啟動"); while(true){ try { while(flag){ logger.info("服務器線程在監聽狀態中"); Socket socket = serverSocket.accept(); String key = socket.getRemoteSocketAddress().toString(); SocketThread thread = new SocketThread(socket,key); thread.start(); socketMaps.put(key, thread); logger.info("有客戶端連接:"+key); } } catch (Exception e) { e.printStackTrace(); } } } /** * 處理連接后的數據接收請求內部類 * @author xiang * */ private class SocketThread extends Thread{ private Socket socket; private String key; private OutputStream out; private InputStream in; //構造函數 public SocketThread(Socket socket,String key) { this.socket = socket; this.key = key; } /** * 發送數據 * @param bytes * @throws IOException */ public void sendMassage(byte[] bytes){ try { if(out==null) out = socket.getOutputStream(); out.write(bytes); } catch (Exception e) { e.printStackTrace(); try { closeConnect(); } catch (IOException e1) { e1.printStackTrace(); } socketMaps.remove(key); } } /** * 關閉連接,釋放資源 * @throws IOException */ public void closeConnect() throws IOException{ if(out!=null) out.close(); if(in!=null) in.close(); if(socket!=null && socket.isConnected()) socket.close(); } @Override public void run() { byte[] receivBuf = new byte[BUFFER_SIZE]; int recvMsgSize; try { in = socket.getInputStream(); out = socket.getOutputStream(); while ((recvMsgSize = in.read(receivBuf)) != -1) { String receivedData = new String(receivBuf, 0, recvMsgSize); System.out.println("Reverve form[port" + socket.getPort() + "]:" + receivedData); System.out.println("Now the size of socketMaps is" + socketMaps.size()); /************************************************************** * * 接收數據后的處理過程 * **************************************************************/ } // response to client byte [] sendByte = "The Server has received" .getBytes(); // out.write(sendByte, 0, sendByte.length); out.write(sendByte); System.out.println( "To Cliect[port:" + socket.getPort() + "] 回復客戶端的消息發送成功" ); closeConnect(); socketMaps.remove(key); } catch (Exception e) { e.printStackTrace(); try { closeConnect(); } catch (IOException e1) { e1.printStackTrace(); } } } ////////////// public int getport(){ return socket.getPort(); } } //. end SocketThread } |
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
原文鏈接:http://www.cnblogs.com/xiangBlog/archive/2017/05/06/6816901.html