三次握手創建TCP之後開始傳輸數據。html
Accept後對於服務端來講整個socket建立完畢,直接進入read狀態。read是一個阻塞調用,所謂阻塞是指服務器進入等待,直到read返回。java
read實際上是的主要時間是等待數據ready:api
因此read阻塞的時間至少須要T1+T2+T3,其中T1+T2的時間爲等待數據的時間服務器
接下來用java源碼來演示BIO的過程,爲了看到效果特地在客戶端加入了兩次sleep來標識客戶端IO的時間,而服務端的read卻要一直等待阻塞在這個客戶端的IO上。socket
源碼參考async
import java.io.InputStream; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.text.SimpleDateFormat; import java.util.Date; public class SocketBioServer { static SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); public static void main(String[] args) { try { ServerSocket serverSocket = new ServerSocket(); serverSocket.bind(new InetSocketAddress("localhost", 8080)); while (true) { Socket socket = serverSocket.accept(); System.out.println(time() + "->accepted, begin to read......"); String result = readBytes(socket.getInputStream()); System.out.println(time() + "->" + result); socket.close(); } } catch (Exception ex) { ex.printStackTrace(); } } static String readBytes(InputStream is) throws Exception { long start = 0; int total = 0; long begin = System.currentTimeMillis(); int count = 0; while ((count = is.read()) > -1) {//block,有數據寫入的時候纔會返回值。客戶端關閉後纔會返回-1 if (start == 0) { start = System.currentTimeMillis(); } total += count; } //讀完數據的時間 long end = System.currentTimeMillis(); return "wait=" + (start - begin) + "ms,read=" + (end - start) + "ms,total=" + total + "bs"; } static String time() { return sdf.format(new Date()); } }
import java.net.InetSocketAddress; import java.net.Socket; public class SocketBioClient { public static void main(String[] args) { try { Socket s = new Socket(); s.connect(new InetSocketAddress("localhost", 8080)); Thread.sleep(5000);//模擬數據發送前的等待 s.getOutputStream().write(prepareBytes()); Thread.sleep(1000);//模擬寫入數據須要的時間 s.close();//關閉後客戶端才能返回-1 } catch (Exception ex) { ex.printStackTrace(); } } static byte[] prepareBytes() { byte[] bytes = new byte[1024 * 1024 * 1]; for (int i = 0; i < bytes.length; i++) { bytes[i] = 1; } return bytes; } }
23:03:14->accepted, begin to read...... 23:03:20->wait=5005ms,read=1002ms,total=1048576bs
經過上述能夠看到read一直阻塞等待客戶端的IO寫入。tcp