服務器server端:
private ServerSocket server;// 創建了ServerSocket對象
// 存放所有客戶端輸出流的集合,並初始化
private List<PrintWriter> allOut = new ArrayList<PrintWriter>();
// 向集合中添加元素
private synchronized void addOut(PrintWriter out) {
allOut.add(out);
}
// 從集合中刪除元素
private synchronized void removeOut(PrintWriter out) {
allOut.remove(out);
}
// 遍歷集合向所有的客戶端發送信息
private synchronized void sendMessage(String msg) {
for (PrintWriter out : allOut) {
out.println(msg);
}
}
/**
* 構造方法,用來初始化ServerSocket
*
* @throws IOException
*/
public Server() throws IOException {
try {
server = new ServerSocket(8088);
} catch (IOException e) {
e.printStackTrace();
throw e;
}
}
public void start() throws IOException {
while (true) {
try {
Socket socket = server.accept();
/**
* 當一個客戶端連接後,應該啓動一個線程,來負責與客戶端的交互 這樣才能循環接待不同的客戶端
*/
ClientHandler hander = new ClientHandler(socket);
Thread thread = new Thread(hander);
// 啓動線程
thread.start();
} catch (IOException e) {
e.printStackTrace();
throw e;
}
}
}
public static void main(String[] args) {
Server server = null;
try {
server = new Server();
server.start();
} catch (IOException e) {
System.out.println("服務器啓動失敗");
}
}
/**
* 啓動線程的成員內部類
*
* @author Admin
*
*/
class ClientHandler implements Runnable {
private Socket socket;
public ClientHandler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
PrintWriter writer = null;
try {
// 向客戶端發送信息
writer = new PrintWriter(new OutputStreamWriter(
socket.getOutputStream(), "utf-8"), true);
addOut(writer);
// 讀取客戶端的信息
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream(), "utf-8"));
String msg = null;
while ((msg = reader.readLine()) != null) {
// 將客戶端發送過來的信息轉發給客戶端
sendMessage(msg);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 處理客戶端斷開連接後的工作
// 將客戶端的輸出流從集合中移除
removeOut(writer);
}
}
}
客戶端client端:
// 創建與服務端通訊的Socket
private Socket socket;
public Client() throws IOException {
try {
socket = new Socket("localhost", 8088);
} catch (IOException e) {
e.printStackTrace();
throw e;
}
}
// 客戶端開始工作的方法
public void start() {
// 啓動線程,用於讀取服務端發送過來的信息
ServerHandler handler = new ServerHandler();
Thread thread = new Thread(handler);
// 啓動線程
thread.start();
/**
* 循環從控制檯輸入信息發送至服務端
*/
Scanner sca = new Scanner(System.in);
try {
PrintWriter writer = new PrintWriter(new OutputStreamWriter(
socket.getOutputStream(), "utf-8"), true);
String msg = null;
while (true) {
msg = sca.nextLine();
writer.println(msg);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Client c = null;
try {
c = new Client();
c.start();
} catch (IOException e) {
System.out.println("連接失敗");
}
}
// 讀取服務端發送過來的信息的線程
class ServerHandler implements Runnable {
@Override
public void run() {
try {
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream(), "utf-8"));
String msg = null;
while ((msg = reader.readLine()) != null) {
System.out.println(msg);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}