在实际的应用中客户端可能需要和服务器端保持长时间的通信,即服务器需要不断地读取客户端数据,并向客户端写入数据;客户端也需要不断地读取服务器数据,并向服务器写入数据。
简单实现代码如下:
1 public class MyServer {
2 //定义保存所有Socket的ArrayList
3 public staticArrayList socketList = newArrayList();
4
5 public static voidmain(String[] args) throws IOException {
6 // TODOAuto-generated method stub
7 ServerSocket ss = newServerSocket(30000);
8 while(true){
9 //此代码会阻塞,将一直等待别人连接
10 Socket s = ss.accept();
11 socketList.add(s);
12 //每当客户端连接后启动一条ServerThread线程为该客户端服务
13 new Thread(newServerThread(s)).start();
14 }
15 }
16 }
17 服务端通信线程
18 public classServerThread implements Runnable {
19 //定义当前线程所处理的Socket
20 Socket s = null;
21 //该线程所处理的Socket所对应的输入流
22 BufferedReader br = null;
23 public ServerThread(Socket s) throws IOException {
24 this.s = s;
25 //初始化该Socket对应的输入流
26 br = newBufferedReader(new InputStreamReader(s.getInputStream(),
27 "utf-8"));
28 }
29 @Override
30 public void run() {
31 // TODOAuto-generated method stub
32 try
33 {
34 String content = null;
35 //采用循环不断从Socket中读取客户端发送过来的数据
36 while((content = readFromClient())!=null){
37 //遍历socketList中的每个Socket
38 //将读到的内容向每个Socket发送一次
39 for(Socket s : MyServer.socketList){
40 OutputStream os = s.getOutputStream();
41 os.write((content + "\n").getBytes("utf-8"));//注意发送消息的时候一定要加换行符,因为在readLine的时候看的就是换行符
42 }
43 }
44 }catch(IOException e) {
45 e.printStackTrace();
46 }
47 }
48
49 public String readFromClient()
50 {
51 try{
52 return br.readLine();
53 }catch(IOException e){ //如果捕捉到异常,表明该Socket对应的客户端已经被关闭
54 //删除该Socket
55 MyServer.socketList.remove(s);
56 }
57 return null;
58 }
59 }
public classMainActivity extends Activity {
EditText input, show;
Button send;
OutputStream os;
Handler handler;
@Override
protected voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
input = (EditText) findViewById(R.id.input);
send = (Button) findViewById(R.id.send);
show = (EditText) findViewById(R.id.show);
handler = new Handler() {
public voidhandleMessage(android.os.Message msg) {
if (msg.what == 0x123) {
show.append("\n" + msg.obj.toString());
}
};
};
newAsyncTask(){
@Override
protected String doInBackground(String... params) {
// TODOAuto-generated method stub
Socket s;
try {
s = new Socket("192.168.1.75", 30000);
//客户端启动ClientThread线程,不断读取来自服务器的数据
new Thread(newClientThread(s, handler)).start();
os = s.getOutputStream();
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
}.execute("");
send.setOnClickListener(newOnClickListener() {
@Override
public voidonClick(View v) {
// TODOAuto-generated method stub
try {
//将用户在文本框中输入的内容写入网络
os.write((input.getText().toString() + "\r\n")
.getBytes("utf-8"));
input.setText("");
} catch(IOException e) {
// TODOAuto-generated catch block
e.printStackTrace();
}
}
});
}
}
客户端通信线程
public classClientThread implements Runnable {
private Socket s; //该线程负责处理的Socket
private Handler handler;
//该线程所处理的Socket对应的输入流
BufferedReader br = null;
public ClientThread(Socket s, Handler handler) throws IOException {
this.s = s;
this.handler = handler;
br = newBufferedReader(new InputStreamReader(s.getInputStream()));
}
@Override
public void run() {
// TODOAuto-generated method stub
try {
String content = null;
//不断读取Socket输入流中的内容
while ((content = br.readLine()) != null) {
//每当读到来自服务器的数据后,发送消息通知程序界面显示数据
Message msg = newMessage();
msg.what = 0x123;
msg.obj = content;
handler.sendMessage(msg);
}
} catch(Exception e) {
e.printStackTrace();
}
}
}