在實際應用中,Server老是在指定的端口上監聽是否有Client請求,一旦監聽到Client請求,Server就會啓動一個線程來響應該請求,而Server自己在啓動完線程以後立刻又進入監聽狀態。android
示例:Socket應用之簡易聊天室服務器
當一個Client鏈接Server以後,Server將向全部Client發送一個消息,這就須要Server和Client都一直處於監聽狀態。app
在Server,1. 經過一個List來存儲全部鏈接進來的Socket 2. 爲每一個client開啓了一個線程來響應請求。socket
服務端程序線程
public class Server {rem
private static final int SERVER_PORT = 54321;get
private static List<Socket> mClientList = new ArrayList<Socket>();it
private ExecutorService mExecutorService;io
private ServerSocket mServerSocket;class
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) { }
}