公司要实现一个简单的聊天功能,提前研究一下Socket通信,而公司的服务端功能又没有实现,所以这里就把服务端的功能放到一个界面实现了。
直接上代码:
复制代码
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<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <EditText android:id="@+id/et_ip" android:layout_width="0dp" android:layout_height="wrap_content" android:hint="IP:端口" android:text="127.0.0.1:8081" android:layout_margin="10dp" android:padding="10dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@+id/btn_connect" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/btn_connect" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" app:layout_constraintRight_toRightOf="parent" android:layout_margin="10dp" android:text="连接"/> <TextView android:id="@+id/tv_receive" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="接受数据:" app:layout_constraintTop_toBottomOf="@+id/et_ip" app:layout_constraintLeft_toLeftOf="parent" android:textSize="14sp" android:layout_margin="10dp"/> <ScrollView android:id="@+id/sv_content" android:layout_width="match_parent" android:layout_height="200dp" app:layout_constraintTop_toBottomOf="@+id/tv_receive" app:layout_constraintLeft_toLeftOf="parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/tv_content" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="聊天内容" android:textColor="#000" android:textSize="16sp" android:layout_margin="10dp"/> </LinearLayout> </ScrollView> <EditText android:id="@+id/et_input" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="发送内容" android:layout_margin="10dp" android:padding="10dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toBottomOf="@+id/sv_content" /> <Button android:id="@+id/btn_service" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintTop_toBottomOf="@+id/et_input" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@+id/btn_send" android:layout_margin="10dp" android:text="服务端发送"/> <Button android:id="@+id/btn_send" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintTop_toBottomOf="@+id/et_input" app:layout_constraintLeft_toRightOf="@+id/btn_service" app:layout_constraintRight_toRightOf="parent" android:layout_margin="10dp" android:text="发送"/> </androidx.constraintlayout.widget.ConstraintLayout>
主要代码:
复制代码
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
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334package com.app.socketdemo; import android.annotation.SuppressLint; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.text.Html; import android.text.TextUtils; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ScrollView; import android.widget.TextView; import android.widget.Toast; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import androidx.appcompat.app.AppCompatActivity; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; public class MainActivity extends AppCompatActivity { @BindView(R.id.et_ip) EditText etIp; @BindView(R.id.btn_connect) Button btnConnect; @BindView(R.id.tv_receive) TextView tvReceive; @BindView(R.id.tv_content) TextView tvContent; @BindView(R.id.et_input) EditText etInput; @BindView(R.id.btn_send) Button btnSend; @BindView(R.id.sv_content) ScrollView svContent; @BindView(R.id.btn_service) Button btnService; private StringBuffer strMsg = new StringBuffer(); private final int MESSAGE_ERROR = 0; private final int MESSAGE_SUCCEED = 1; private final int MESSAGE_RECEIVE = 2; private Socket sock; private OutputStream outx; private InputStream inx; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); //启动服务端 new Thread(() -> new Server().startService()).start(); } @OnClick({R.id.btn_connect, R.id.btn_service, R.id.btn_send}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.btn_connect://连接服务端 String strip = etIp.getText().toString().trim(); if (strip.indexOf(":") >= 0) { //启动连接 new Socket_thread(strip).start(); } break; case R.id.btn_service: if (!TextUtils.isEmpty(etInput.getText().toString())) { sendString("服务端:" + etInput.getText().toString().trim()); etInput.setText(""); } else { Toast.makeText(this, "输入不可为空", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_send: if (!TextUtils.isEmpty(etInput.getText().toString())) { sendStrSocket("客户端:" + etInput.getText().toString().trim()); etInput.setText(""); } else { Toast.makeText(this, "输入不可为空", Toast.LENGTH_SHORT).show(); } break; } } /** * 连接服务器 */ class Socket_thread extends Thread { private String IP = "";//ip地址 private int PORT = 0;//端口号 public Socket_thread(String strip) { //如: 127.0.0.1:8081 String[] stripx = strip.split(":"); this.IP = stripx[0]; this.PORT = Integer.parseInt(stripx[1]); } @Override public void run() { try { disSocket(); //连接服务器,此处会一直处于阻塞,直到连接成功 sock = new Socket(this.IP, this.PORT); //阻塞停止,表示连接成功 setMessage("连接成功", MESSAGE_SUCCEED); } catch (Exception e) { setMessage("连接服务器时异常", MESSAGE_ERROR); e.printStackTrace(); return; } try { //获取到输入输出流 outx = sock.getOutputStream(); inx = sock.getInputStream(); } catch (Exception e) { setMessage("获取输入输出流异常", MESSAGE_ERROR); e.printStackTrace(); return; } new Inx().start(); } } /** * 循环接收数据 */ class Inx extends Thread { @Override public void run() { while (true) { byte[] bu = new byte[1024]; try { int conut = inx.read(bu);//设备重启,异常 将会一直停留在这 if (conut == -1) { setMessage("服务器断开", MESSAGE_ERROR); disSocket(); return; } String strread = new String(bu, "GBK").trim(); setMessage(strread, MESSAGE_RECEIVE); } catch (IOException e) { System.out.println(e); } } } } /** * 断开连接 */ private void disSocket() { if (sock != null) { try { outx.close(); inx.close(); sock.close(); sock = null; } catch (Exception e) { setMessage("断开连接时发生错误", MESSAGE_ERROR); } } } @SuppressLint("HandlerLeak") private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.arg1) { case MESSAGE_ERROR: disSocket(); strMsg.append(msg.obj + "<br>"); tvContent.setText(Html.fromHtml(strMsg.toString())); break; case MESSAGE_SUCCEED: strMsg.append(msg.obj + "<br>"); tvContent.setText(Html.fromHtml(strMsg.toString())); break; case MESSAGE_RECEIVE: //收到数据 strMsg.append(msg.obj); if (!strMsg.toString().substring(strMsg.length() - 4, strMsg.length()).equals("<br>")) { strMsg.append("<br>"); } tvContent.setText(Html.fromHtml(strMsg.toString())); svContent.fullScroll(ScrollView.FOCUS_DOWN); break; default: break; } } }; /** * 发送消息 */ private void sendStrSocket(final String senddata) { new Thread(new Runnable() { @Override public void run() { try { String str = "<font color='#EE2C2C'>" + senddata + "</font>"; outx.write(str.getBytes("gbk"));//"utf-8" } catch (Exception e) { setMessage("数据发送异常", MESSAGE_ERROR); } } }).start(); } /** * 消息处理 */ private void setMessage(String obj, int arg1){ Message message = new Message(); message.arg1 = arg1; message.obj = obj; handler.sendMessage(message); } /*************************************************************服务端(用于测试)**********************************************************************/ private String msg = ""; public class Server { ServerSocket serverSocket = null; public final int port = 8081; public Server() { //输出服务器的IP地址 try { InetAddress addr = InetAddress.getLocalHost(); serverSocket = new ServerSocket(port); } catch (IOException e) { e.printStackTrace(); } } public void startService() { try { while (true) { Socket socket = null; socket = serverSocket.accept();//等待一个客户端的连接,在连接之前,此方法是阻塞的 new ConnectThread(socket).start(); new ConnectThread1(socket).start(); } } catch (IOException e) { e.printStackTrace(); } } /** * 向客户端发送信息 */ class ConnectThread extends Thread { Socket socket = null; public ConnectThread(Socket socket) { super(); this.socket = socket; } @Override public void run() { try { DataOutputStream out = new DataOutputStream(socket.getOutputStream()); while (true) { Thread.sleep(1000); if (!TextUtils.isEmpty(msg)) { String str = "<font color='#4F94CD'>" + msg + "</font>"; out.write(str.getBytes("gbk")); out.flush(); msg = ""; } } } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } } /** * 接收客户端信息 */ class ConnectThread1 extends Thread { Socket socket = null; public ConnectThread1(Socket socket) { super(); this.socket = socket; } @Override public void run() { try { DataInputStream inp = new DataInputStream(socket.getInputStream()); while (true) { byte[] bu = new byte[1024]; int conut = inp.read(bu);//设备重启,异常 将会一直停留在这 if (conut == -1) { setMessage("服务器断开", MESSAGE_ERROR); return; } String strread = new String(bu, "GBK").trim(); setMessage(strread, MESSAGE_RECEIVE); } } catch (IOException e) { e.printStackTrace(); } } } } private void sendString(String str) { msg = str; } }
运行效果:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持靠谱客。
最后
以上就是冷酷电话最近收集整理的关于Android Socket通信的简单实现的全部内容,更多相关Android内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复