java 编程原理_Java网络编程 -- 网络编程基础原理
Hello,今天記錄下 Java網絡編程?-->?網絡編程基礎原理。
一起學習,一起進步。繼續沉淀,慢慢強大。希望這文章對您有幫助。若有寫的不好的地方,歡迎評論給建議哈!
初寫博客不久,我是楊展浩。這是我的第十五篇博客。加油!!!
1、網絡編程(Socket) 概念
注意:Socket 不是 Java 中獨有的概念,而是一個語言無關標準。 任何可以實現網絡編程的編程語言都有 Socket。
1.1、Socket的定義
網絡上的兩個程序通過一個雙向的通信連接實現數據的交換,這個連接的一端稱為一個socket。建立網絡通信連接至少要一個端口號。 socket 本質是編程接口(一套API),對 TCP/IP 的封裝,TCP/IP 也要提供可供程序員做網絡開發所用的接口,這就是 Socket 編程接口; HTTP 是轎車,提供了封裝或者顯示數據的具體形式; Socket 是發動機,提供了網絡通信的能力。
Socket 的英文原義是“孔”或“插座”。作為 BSD UNIX 的進程通信機制,取后一種意思。通常也稱作"套接字",用于描述 IP 地址和端口,是一個通信鏈的句柄,可以用來實現不同虛擬機或不同計算機之間的通信。在 Internet 上的主機一般運行了多個服務軟件,同時提供幾種服務。每種服務都打開一個 Socket,并綁定到一個端口上,不同的端口對應于不同的服務。Socket 正如其英文原義那樣,像一個多孔插座。一臺主機猶如布滿各種插座的房間,每個插座有一個編號,有的插座提供 220 伏交流電, 有的提供 110 伏交流電,有的則提供有線電視節目。 客戶軟件將插頭插到不同編號的插座,就可以得到不同的服務。
1.2、Socket 連接步驟
根據連接啟動的方式以及本地套接字要連接的目標,套接字之間的連接過程可以分為三個步驟:服務器監聽,客戶端請求,連接確認。【如果包含數據交互+斷開連接,那么一共是五個步驟】
(1)服務器監聽:是服務器端套接字并不定位具體的客戶端套接字,而是處于等待連接的狀態,實時監控網絡狀態。
(2)客戶端請求:是指由客戶端的套接字提出連接請求,要連接的目標是服務器端的套接字。為此,客戶端的套接字必須首先描述它要連接的服務器的套接字,指出服務器端套接字的地址和端口號,然后就向服務器端套接字提出連接請求。
(3)連接確認:是指當服務器端套接字監聽到或者說接收到客戶端套接字的連接請求,它就響應客戶端套接字的請求,建立一個新的線程,把服務器端套接字的描述發給客戶端,一旦客戶端確認了此描述,連接就建立好了。而服務器端套接字繼續處于監聽狀態,繼續接收其他客戶端套接字的連接請求。
時序圖如下:
1.3、Java 中的 Socket
在 java中, java.net 包是網絡編程的基礎類庫。其中 ServerSocket 和 Socket 是網絡編程的基礎類型。 ServerSocket 是服務端應用類型。 Socket 是建立連接的類型。 當連接建立成功后,服務器和客戶端都會有一個 Socket 對象實例,可以通過這個 Socket 對象實例,完成這次會話的所有操作。
對于一個完整的網絡連接來說, Socket 是平等的,一旦雙方建立連接成功后,就沒有服務器客戶端分級情況了。
2、同步 與 異步
同步和異步是針對應用程序和內核的交互而言的。同步指的是用戶進程觸發 IO 操作并等待或者輪詢的去查看 IO 操作是否就緒,而異步是指用戶進程觸發 IO 操作之后,便開始做自己的事情,而當 IO 操作已經完成的時候,用戶進程會得到 OS 告知 IO 操作完成的通知。
以銀行取款為例:
同步 : 自己親自出馬持銀行卡到銀行取錢(程序角度分析:使用同步 IO 時, Java 自己處理 IO 讀寫);
異步 : 委托一小弟拿銀行卡到銀行取錢,然后給你(程序角度分析:使用異步 IO 時, Java 將 IO 讀寫委托給 OS 處理,需要將數據緩沖區地址和大小傳給 OS(銀行卡和密碼), OS 需要支持異步 IO操作 API);
3、阻塞 與 非阻塞
阻塞和非阻塞是針對于進程在訪問數據的時候,根據 IO 操作的就緒狀態來采取的不同方式。說白了是一種讀取或者寫入操作方法的實現方式,阻塞方式下讀取或者寫入方法將一直等待,等待該方法處理完成,進而繼續往下執行程序。而非阻塞方式下,讀取或者寫入方法會立即返回一個狀態值,進而繼續往下執行程序。
以銀行取款為例:
阻塞 : ATM 排隊取款,你只能等待(程序角度分析:使用阻塞 IO 時, Java 調用會一直阻塞到讀寫完成才返回);
非阻塞 : 柜臺取款,取個號,然后坐在椅子上做其它事,等號,廣播會通知你辦理,沒到號你就不能去,你可以不斷問大堂經理排到了沒有,大堂經理如果說還沒到你就不能去(程序角度分析:使用非阻塞 IO 時,如果不能讀寫 Java 調用會馬上返回,當 IO 事件分發器通知可讀寫時再繼續進行讀寫,不斷循環直到讀寫完成)
4、BIO 編程
Blocking IO:同步阻塞的編程方式。BIO 編程方式是JDK1.4 版本之前常用的編程方式。
編程實現過程為:首先在服務端啟動一個 ServerSocket 來監聽網絡請求,客戶端啟動 Socket 發起網絡請求,默認情況下 ServerSocket 會新創建一個線程來處理此次客戶端請求,如果服務端沒有線程可用或可新建,客戶端則會阻塞等待或遭到拒絕。一旦建立好的連接,在通訊過程中,服務端與客戶端之間是同步的。但是在客戶端出現并發請求連接情況,服務端處理效率上比較低。大致結構如下:
BIO --?同步并阻塞,服務器實現模式為一個連接一個線程,即客戶端有連接請求時服務器端就需要啟動一個線程進行處理,如果這個連接不做任何事情會造成不必要的線程開銷,當然可以通過線程池機制改善。BIO 方式適用于連接數目比較小且固定的架構,這種方式對服務器資源要求比較高,并發局限于應用中,JDK1.4 以前的唯一選擇,但程序直觀簡單易理解。
使用線程池機制改善后的 BIO 模型圖如下:通過線程池機制可以減少線程的不必要開銷。
5、NIO 編程
Unblocking IO(New IO):同步非阻塞的編程方式。 NIO 本身是基于事件驅動思想來完成的,其主要想解決的是 BIO 的大并發問題,NIO 基于 Reactor,當 socket有流可讀 或 可寫入socket 時,操作系統會相應的通知應用程序進行處理,應用程序再將流讀取到緩沖區或寫入操作系統。也就是說,這個時候,已經不是一個連接就要對應一個處理線程了,而是一個有效的請求,對應一個線程,當連接沒有數據時,是沒有工作線程來處理的。 NIO 的最重要的地方是當一個連接創建后,不需要對應一個線程,這個連接會被注冊到多路復用器 selector上面,所以所有的連接只需要一個線程就可以搞定,當這個線程中的多路復用器進行輪詢的時候,發現連接上有請求的話,才開啟一個線程進行處理,也就是一個請求一個線程模式。在 NIO 的處理方式中,當一個請求來的話,開啟線程進行處理,可能會等待后端應用的資源(JDBC 連接等),其實這個線程就被阻塞了,當并發的量上來的話,還是會有 BIO 一樣的問題。
同步非阻塞,服務器實現模式為一個請求一個通道處理,即
客戶端發送的連接請求都會注冊到 多路復用器 selector上,多路復用器輪詢到連接有 I/O 請求時才啟動一個線程進行處理
。
NIO 方式適用于連接數目多且連接比較短(輕操作)的架構
,比如聊天服務器,并發局限于應用中,編程復雜,JDK1.4 開始支持。
Buffer:
ByteBuffer, CharBuffer, ShortBuffer, IntBuffer, LongBuffer, FloatBuffer, DoubleBuffer。
Channel:
SocketChannel, ServerSocketChannel。
Selector:
Selector, AbstractSelector。
SelectionKey:
OP_READ, OP_WRITE, OP_CONNECT, OP_ACCEPT。
6、
AIO編程
AsynchronousIO: 異步非阻塞的編程方式
與 NIO 不同,當進行讀寫操作時,只須直接調用
API
的
read
或
write
方法即可。這兩種方法均為異步的,對于讀操作而言,當有流可讀取時,操作系統會將可讀的流傳入 read
方法的緩沖區,并通知應用程序;對于寫操作而言,當操作系統將 write
方法傳遞的流寫入完畢時,操作系統主動通知應用程序。即可以理解為,read/write
方法都是異步的,完成后會主動調用回調函數。在 JDK1.7
中,這部分內容被稱作
NIO.2
,主要在
java.nio.channels
包下
增加了下面四個異步通道:
AsynchronousSocketChannel
AsynchronousServerSocketChannel
AsynchronousFileChannel
AsynchronousDatagramChannel
異步非阻塞,服務器實現模式為一個有效請求一個線程,客戶端的 I/O 請求都是由
OS 先完成了再通知服務器應用去啟動線程進行處理。 AIO 方式使用于連接數目多且連接比較長(重操作)的架構,比如相冊服務器,充分調用 OS
參與并發操作,編程比較復雜,
JDK7
開始支持。
總結
以上是生活随笔為你收集整理的java 编程原理_Java网络编程 -- 网络编程基础原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 冻胚多少钱啊?
- 下一篇: java的使用条件_Java使用条件语句