在同步阻塞模型(BIO)中,ServerSocket負(fù)責(zé)綁定IP地址悲龟,啟動(dòng)監(jiān)聽(tīng)端口屋讶,Socket負(fù)責(zé)發(fā)起連接操作。連接成功之后须教,雙方通過(guò)輸入和輸出流進(jìn)行同步阻塞式通信丑婿。
阻塞操作有:
- connect():客戶端發(fā)送請(qǐng)求,建立連接
- accept():服務(wù)器接受請(qǐng)求,建立連接
- inputStream/outputStream:同步阻塞讀寫
BIO通信模型的服務(wù)端羹奉,通常由一個(gè)獨(dú)立的Acceptor線程負(fù)責(zé)監(jiān)聽(tīng)客戶端的連接秒旋,它接收到客戶端連接請(qǐng)求后為每個(gè)客戶端創(chuàng)建一個(gè)新的線程進(jìn)行鏈路處理,處理完成之后诀拭,通過(guò)輸出流返回應(yīng)答給客戶端迁筛,線程銷毀。這是典型的一請(qǐng)求一應(yīng)答通信模型耕挨。
- Server
監(jiān)聽(tīng)邏輯:
// 線程池處理客戶端請(qǐng)求
ExecutorService executorService = Executors.newFixedThreadPool(3);
// 啟動(dòng)服務(wù)器
ServerSocket serverSocket = new ServerSocket(8000);
while (true) {
// 阻塞直到成功建立連接
Socket socket = serverSocket.accept();
// 在另一線程處理
executorService.submit(() -> handle(socket));
}
serverSocket.close();
處理邏輯:
void handle(Socket socket) {
// 向客戶端發(fā)送當(dāng)前時(shí)間
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream(), "UTF-8"));
writer.write(new Date().toString());
writer.flush();
// 休眠1s后關(guān)閉連接
Thread.sleep(1000);
socket.close();
}
- Client
通信邏輯:
void request(String host, int port) {
// 阻塞直到成功建立連接
Socket socket = new Socket(host, port);
// 通過(guò)輸入流讀取服務(wù)器消息
BufferedReader reader = new BufferedReader(new InputStreamReader(
socket.getInputStream(), "UTF-8"));
StringBuilder sb = new StringBuilder();
while (true) {
// 阻塞直到服務(wù)器消息到達(dá)
String line = reader.readLine();
if (line == null) {
break;
}
sb.append(line);
}
System.out.println("服務(wù)器消息:" + sb.toString());
// 關(guān)閉連接
socket.close();
}
并發(fā)邏輯:
String host = "127.0.0.1";
int port = 8000;
int num = 5;
Runnable runnable = () -> request(host, port);
for (int i = 0; i < num; i++) {
new Thread(runnable).start();
}
- 結(jié)果
同時(shí)發(fā)送5個(gè)請(qǐng)求细卧,而服務(wù)器只有3個(gè)處理線程,則有2個(gè)請(qǐng)求需要等到處理線程釋放后才能被處理筒占。
Thread-1:服務(wù)器消息:Thu Jul 18 10:45:26 CST 2019
Thread-2:服務(wù)器消息:Thu Jul 18 10:45:26 CST 2019
Thread-0:服務(wù)器消息:Thu Jul 18 10:45:26 CST 2019
Thread-3:服務(wù)器消息:Thu Jul 18 10:45:27 CST 2019
Thread-4:服務(wù)器消息:Thu Jul 18 10:45:27 CST 2019