关于Socket编程的基本方法在基础篇里已经讲过,今天把它给完善了。加入了多线程,这样UI线程就不会被阻塞;实现了客户端和服务器的双向通信,只要客户端发起了连接并成功连接后那么两者就可以随意进行通信了。
二、实现
在之前的工程基础上进行修改就可以了。
MyClient工程的main.xml文件不用修改,只需要修改MyClientActivity.java文件,主要是定义了一个继承自Thread类的用于接收数据的类,覆写了其中的run()方法,在这个函数里面接收数据,接收到数据后就通过Handler发送消息,收到消息后在UI线程里更新接收到的数据。完整的内容如下:
1 package com.nan.client;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.io.OutputStream;
6 import java.io.UnsupportedEncodingException;
7 import java.net.Socket;
8 import java.net.UnknownHostException;
9
10 import android.app.Activity;
11 import android.os.Bundle;
12 import android.os.Handler;
13 import android.os.Message;
14 import android.view.View;
15 import android.widget.Button;
16 import android.widget.EditText;
17 import android.widget.TextView;
18 import android.widget.Toast;
19
20
21 public class MyClientActivity extends Activity
22 {
23
private EditText mEditText = null;
24
private Button connectButton = null;
25
private Button sendButton = null;
26
private TextView mTextView = null;
27
28
private Socket clientSocket = null;
29
private OutputStream outStream = null;
30
31
private Handler mHandler = null;
32
33
private ReceiveThread mReceiveThread = null;
34
private boolean stop = true;
35
36
/** Called when the activity is first created. */
37
@Override
38
public void onCreate(Bundle savedInstanceState)
39
{
40
super.onCreate(savedInstanceState);
41
setContentView(R.layout.main);
42
43
mEditText = (EditText)this.findViewById(R.id.edittext);
44
mTextView = (TextView)this.findViewById(R.id.retextview);
45
connectButton = (Button)this.findViewById(R.id.connectbutton);
46
sendButton = (Button)this.findViewById(R.id.sendbutton);
47
sendButton.setEnabled(false);
48
49
//连接按钮监听
50
connectButton.setOnClickListener(new View.OnClickListener()
51
{
52
53
@Override
54
public void onClick(View v)
55
{
56
// TODO Auto-generated method stub
57
try
58
{
59
//实例化对象并连接到服务器
60
clientSocket = new Socket("113.114.170.246",8888);
61
}
62
catch (UnknownHostException e)
63
{
64
// TODO Auto-generated catch block
65
e.printStackTrace();
66
}
67
catch (IOException e)
68
{
69
// TODO Auto-generated catch block
70
e.printStackTrace();
71
}
72
73
displayToast("连接成功!");
74
//连接按钮使能
75
connectButton.setEnabled(false);
76
//发送按钮使能
77
sendButton.setEnabled(true);
78
79
mReceiveThread = new ReceiveThread(clientSocket);
80
stop = false;
81
//开启线程
82
mReceiveThread.start();
83
}
84
});
85
86
//发送数据按钮监听
87
sendButton.setOnClickListener(new View.OnClickListener()
88
{
89
90
@Override
91
public void onClick(View v)
92
{
93
// TODO Auto-generated method stub
94
byte[] msgBuffer = null;
95
//获得EditTex的内容
96
String text = mEditText.getText().toString();
97
try {
98
//字符编码转换
99
msgBuffer = text.getBytes("GB2312");
100
} catch (UnsupportedEncodingException e1) {
101
// TODO Auto-generated catch block
102
e1.printStackTrace();
103
}
104
105
106
try {
107
//获得Socket的输出流
108
outStream = clientSocket.getOutputStream();
109
} catch (IOException e) {
110
// TODO Auto-generated catch block
111
e.printStackTrace();
112
}
113
114
115
try {
116
//发送数据
117
outStream.write(msgBuffer);
118
} catch (IOException e) {
119
// TODO Auto-generated catch block
120
e.printStackTrace();
121
}
122
//清空内容
123
mEditText.setText("");
124
displayToast("发送成功!");
125
}
126
});
127
128
//消息处理
129
mHandler = new Handler()
130
{
131
@Override
132
public void handleMessage(Message msg)
133
{
134
//显示接收到的内容
135
mTextView.setText((msg.obj).toString());
136
}
137
};
138
139
}
140
141
//显示Toast函数
142
private void displayToast(String s)
143
{
144
Toast.makeText(this, s, Toast.LENGTH_SHORT).show();
145
}
146
147
148
private class ReceiveThread extends Thread
149
{
150
private InputStream inStream = null;
151
152
private byte[] buf;
153
private String str = null;
154
155
ReceiveThread(Socket s)
156
{
157
try {
158
//获得输入流
159
this.inStream = s.getInputStream();
160
} catch (IOException e) {
161
// TODO Auto-generated catch block
162
e.printStackTrace();
163
}
164
}
165
166
@Override
167
public void run()
168
{
169
while(!stop)
170
{
171
this.buf = new byte[512];
172
173
try {
174
//读取输入数据(阻塞)
175
this.inStream.read(this.buf);
176
} catch (IOException e) {
177
// TODO Auto-generated catch block
178
e.printStackTrace();
179
}
180
181
//字符编码转换
182
try {
183
this.str = new String(this.buf, "GB2312").trim();
184
} catch (UnsupportedEncodingException e) {
185
// TODO Auto-generated catch block
186
e.printStackTrace();
187
}
188
189
Message msg = new Message();
190
msg.obj = this.str;
191
//发送消息
192
mHandler.sendMessage(msg);
193
194
}
195
}
196
197
198
}
199
200
@Override
201
public void onDestroy()
202
{
203
super.onDestroy();
204
205
if(mReceiveThread != null)
206
{
207
stop = true;
208
mReceiveThread.interrupt();
209
}
210
}
211
212 }