在实际应用中,Server总是在指定的端口上监听是否有Client请求,一旦监听到Client请求,Server就会启动一个线程来响应该请求,而Server本身在启动完线程之后马上又进入监听状态。
示例:Socket应用之简易聊天室
当一个Client连接Server之后,Server将向所有Client发送一个消息,这就需要Server和Client都一直处于监听状态。
在Server,1. 通过一个List来存储所有连接进来的Socket 2. 为每个client开启了一个线程来响应请求。
服务端程序
public class Server {
private static final int SERVER_PORT = 54321;
private static List<Socket> mClientList = new ArrayList<Socket>();
private ExecutorService mExecutorService;
private ServerSocket mServerSocket;
public Server () {
try {
mServerSocket = new ServerSocket(SERVER_PORT);
mExecutorService = Executors.newCachedThreadPool();
socket client = null;
while(true) {
client = mServerSocket.accept();
mClientList.add(client);
mExecutorService.execute(new ThreadServer(client));
}
} catch (IOException e) { }
}
// 为每个client独立开启一个线程。
static class ThreadServer implements Runnable {
private Socket mSocket;
private BufferedReader mBufferedReader;
private PrintWriter mPrintWriter;
private String mStrMsg;
public ThreadServer(Socket socket) throw IOException {
mSocket = socket;
mBufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream));
mStrMsg = “user(”+mSocket.getInetAddress()+”) come, total client count: ” + mClientList.size();
sendMessage();
}
public void run() {
try {
while((mStrMsg = mBufferedReader.readLine())!=null){
if(mStrMsg.trim().equals(“exit”)) {
// 当一个client退出时
mClientList.remove(mSocket);
mBufferedReader.close();
mPrintWriter.close();
mStrMsg = “user(”+mSocket.getInetAddress()+”) exit, total client count: ” + mClientList.size();
mSocket.close();
sendMessage();
break;
} else {
mStrMsg = mSocket.getInetAddress() + “:”+ mStrMsg;
sendMessage();
} // else
} // while
} catch(IOException e) { }
}
// 发送信息给所有client
private void sendMessage() throws IOException {
for(Socket socket : mClientList) {
mPrintWriter = new PrintWriter(client.getOutputStream(), true);
mPrintWriter.println(mStrMsg);
}
}
}
}
客户端程序
// android client app
在onCreate方法中
// 点击“登录”连接服务器
mSocket = new Socket(SERVER_IP, SERVER_PORT);
// 取得输入输出流
mBufferedReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
mPrintWriter = new PrintWriter(mSocket.getOutputStream(), true);
// 点击“发送消息”
String msg = mMsgBox.getText().toString();
mPrintWriter.print(msg);
mPrintWriter.flush();
// 开启线程监听服务器发来的消息
new Thread(mRunnable).start();
// 监听Server发来消息的线程
private Runnable mRunnable = new Runnable(){
public void run() {
while(true) {
try {
if((mStrMsg = mBufferedReader.readLine())!=null) {
mStrMsg += “\n”;
mHandler.sendMessage(mHandler.obtainMessage());
}
} catch(Exception e) { }
}
}
};
Handler mHandler = new Hander(){
super.handleMessage(msg);
try {
mMsgLabel.append(mstrMsg);
} catch(Exception e) { }
}