java必學(xué)必會(huì)之網(wǎng)絡(luò)編程
一、網(wǎng)絡(luò)基礎(chǔ)概念
首先理清一個(gè)概念:網(wǎng)絡(luò)編程 != 網(wǎng)站編程,網(wǎng)絡(luò)編程現(xiàn)在一般稱(chēng)為T(mén)CP/IP編程。
二、網(wǎng)絡(luò)通信協(xié)議及接口
三、通信協(xié)議分層思想
四、參考模型
五、IP協(xié)議
每個(gè)人的電腦都有一個(gè)獨(dú)一無(wú)二的IP地址,這樣互相通信時(shí)就不會(huì)傳錯(cuò)信息了。
IP地址是用一個(gè)點(diǎn)來(lái)分成四段的,在計(jì)算機(jī)內(nèi)部IP地址是用四個(gè)字節(jié)來(lái)表示的,一個(gè)字節(jié)代表一段,每一個(gè)字節(jié)代表的數(shù)最大只能到達(dá)255。
六、TCP協(xié)議和UDP協(xié)議
TCP和UDP位于同一層,都是建立在IP層的基礎(chǔ)之上。由于兩臺(tái)電腦之間有不同的IP地址,因此兩臺(tái)電腦就可以區(qū)分開(kāi)來(lái),也就可以互相通話(huà)了。通話(huà)一般有兩種通話(huà)方式:第一種是TCP,第二種是UDP。TCP是可靠的連接,TCP就像打電話(huà),需要先打通對(duì)方電話(huà),等待對(duì)方有回應(yīng)后才會(huì)跟對(duì)方繼續(xù)說(shuō)話(huà),也就是一定要確認(rèn)可以發(fā)信息以后才會(huì)把信息發(fā)出去。TCP上傳任何東西都是可靠的,只要兩臺(tái)機(jī)器上建立起了連接,在本機(jī)上發(fā)送的數(shù)據(jù)就一定能傳到對(duì)方的機(jī)器上,UDP就好比發(fā)電報(bào),發(fā)出去就完事了,對(duì)方有沒(méi)有接收到它都不管,所以UDP是不可靠的。TCP傳送數(shù)據(jù)雖然可靠,但傳送得比較慢,UDP傳送數(shù)據(jù)不可靠,但是傳送得快。
七、Socket編程
一般的網(wǎng)絡(luò)編程都稱(chēng)為Socket編程,Socket的英文意思是“插座”。
兩臺(tái)電腦都安裝上一個(gè)插座,然后使用一根線(xiàn)的兩端插到兩臺(tái)電腦的插座上,這樣兩臺(tái)電腦就建立好了連接。這個(gè)插座就是Socket。
因?yàn)榛ハ嘀g都能互相通信,我說(shuō)你是我的Server只是從邏輯意義上來(lái)講,我應(yīng)該把東西先發(fā)到你那里去,然后由你來(lái)處理,轉(zhuǎn)發(fā)。所以你叫Server。但從技術(shù)意義上來(lái)講,只有TCP才會(huì)分Server和Client。對(duì)于UDP來(lái)說(shuō),從嚴(yán)格意義上來(lái)講,并沒(méi)有所謂的Server和Client。TCP的Server的插座就叫ServerSocket,Client的插座就叫Socket。
兩臺(tái)計(jì)算機(jī)互相連接,那么首先必須得知道它們的IP地址,但是只提供IP地址是不夠的,還必須要有連接的端口號(hào),也就是要連接到哪個(gè)應(yīng)用程序上。
端口號(hào)是用來(lái)區(qū)分一臺(tái)機(jī)器上不同的應(yīng)用程序的。端口號(hào)在計(jì)算機(jī)內(nèi)部是占2個(gè)字節(jié)。一臺(tái)機(jī)器上最多有65536個(gè)端口號(hào)。一個(gè)應(yīng)用程序可以占用多個(gè)端口號(hào)。端口號(hào)如果被一個(gè)應(yīng)用程序占用了,那么其他的應(yīng)用程序就無(wú)法再使用這個(gè)端口號(hào)了。記住一點(diǎn),我們編寫(xiě)的程序要占用端口號(hào)的話(huà)占用1024以上的端口號(hào),1024以下的端口號(hào)不要去占用,因?yàn)橄到y(tǒng)有可能會(huì)隨時(shí)征用。端口號(hào)本身又分為T(mén)CP端口和UDP端口,TCP的8888端口和UDP的8888端口是完全不同的兩個(gè)端口。TCP端口和UDP端口都有65536個(gè)。
八、TCP Socket通信模型
九、Socket使用范例
服務(wù)器端ServerSocket
import java.net.*; import java.io.*; public class TestServerSocket{ public static void main(String args[]) throws Exception{ ServerSocket ss = new ServerSocket(6666); /*創(chuàng)建一個(gè)ServerSocket對(duì)象時(shí)往往會(huì)給它指定一個(gè)端口號(hào) 指定端口號(hào)的意思是這個(gè)new出來(lái)的ServerSocket對(duì)象要使用的 是哪一個(gè)端口號(hào),通過(guò)哪一個(gè)端口號(hào)來(lái)監(jiān)聽(tīng)客戶(hù)端的連接 因此指定一個(gè)端口號(hào)的意義就是為了告訴計(jì)算機(jī)ServerSocket對(duì)象 在哪個(gè)地方監(jiān)聽(tīng)客戶(hù)端的連接*/ /*服務(wù)器端接收客戶(hù)端連接的請(qǐng)求是不間斷地接收的,所以服務(wù)器端的 編程一般都是死循環(huán),永不休止地運(yùn)行著。*/ while(true){ Socket s = ss.accept(); /*在服務(wù)器端調(diào)用accept()方法接受客戶(hù)端的連接對(duì)象,accept()方法是 一個(gè)阻塞式方法,一直在傻傻地等待著是否有客戶(hù)端申請(qǐng)連接上來(lái) 然后服務(wù)器端的Socket插座就和客戶(hù)端的Socket插座建立了連接了*/ /*客戶(hù)端能否連接上服務(wù)器端,取決于服務(wù)器端是否接受客戶(hù)端的連接請(qǐng)求 如果接受了客戶(hù)端的連接請(qǐng)求,那么在服務(wù)器端就安裝上一個(gè)Socket插座 通過(guò)這個(gè)插座與連接上的客戶(hù)端就可以建立連接,互相通信了*/ System.out.println("A Client Connected!"); /*使用InputStream流接收從客戶(hù)端發(fā)送過(guò)來(lái)的信息,使用DataInputStream數(shù)據(jù)流處理接收到的信息*/ DataInputStream dis = new DataInputStream(s.getInputStream()); /*使用readUTF(方法將接收到的信息全部讀取出來(lái),存儲(chǔ)到變量str里面 readUTF()方法也是一個(gè)阻塞式方法,會(huì)傻傻地等待客戶(hù)端發(fā)送信息過(guò)來(lái),然后將接收到的信息讀取出來(lái) 如果客戶(hù)端不寫(xiě)東西過(guò)來(lái),它就一直在服務(wù)器端傻傻地等待著,直到客戶(hù)端寫(xiě)東西過(guò)來(lái)為止 堵塞式的方法效率往往是不高的,比如說(shuō)一個(gè)客戶(hù)端連接上來(lái)了,但是它遲遲不發(fā)送信息, 那么服務(wù)器端的程序就阻塞住了,這樣另外一個(gè)客戶(hù)端就連接不上來(lái)了,因?yàn)榱硗庖粋€(gè)客戶(hù)端要想連接 上服務(wù)器端,就必須得在服務(wù)器端調(diào)用accept()方法,可accept()方法必須得在下一次循環(huán)時(shí)才能夠被 調(diào)用,現(xiàn)在服務(wù)器端的程序運(yùn)行到調(diào)用readUTF()這個(gè)方法時(shí)就阻塞住了,它要等待著已經(jīng)連接上來(lái)的 那個(gè)客戶(hù)端發(fā)送信息過(guò)來(lái)后將信息讀取出來(lái),如果客戶(hù)端一直不發(fā)信息到服務(wù)器端,那么readUTF()方法 就一直無(wú)法讀取到信息,那么服務(wù)器端的程序會(huì)阻塞在這里,無(wú)法進(jìn)行下次循環(huán),這樣其他的客戶(hù)端就 無(wú)法連接到服務(wù)器端了*/ String str = dis.readUTF(); System.out.println(str); } } }
客戶(hù)端Socket
import java.net.*; import java.io.*; public class TestClientSocket{ public static void main(String args[]) throws Exception{ Socket s = new Socket("127.0.0.1",6666); /*Client申請(qǐng)連接到Server端上*/ /*連接上服務(wù)器端以后,就可以向服務(wù)器端輸出信息和接收從服務(wù)器端返回的信息 輸出信息和接收返回信息都要使用流式的輸入輸出原理進(jìn)行信息的處理*/ /*這里是使用輸出流OutputStream向服務(wù)器端輸出信息*/ OutputStream os = s.getOutputStream(); DataOutputStream dos = new DataOutputStream(os); Thread.sleep(30000);/*客戶(hù)端睡眠30秒后再向服務(wù)器端發(fā)送信息*/ dos.writeUTF("Hello Server!"); } }
客戶(hù)端通過(guò)端口6666向服務(wù)器端請(qǐng)求連接,服務(wù)器端接受客戶(hù)端的連接請(qǐng)求以后,就在服務(wù)器端上安裝一個(gè)Socket,然后讓這個(gè)Socket與客戶(hù)端的Socket連接,這樣服務(wù)器端就可以與客戶(hù)端互相通信了,當(dāng)有另外一個(gè)客戶(hù)端申請(qǐng)連接時(shí),服務(wù)器端接受了以后,又會(huì)安裝另外一個(gè)Socket與這個(gè)客戶(hù)端的Socket進(jìn)行連接。
- Java的Socket網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)入門(mén)教程
- Java套接字(Socket)網(wǎng)絡(luò)編程入門(mén)
- 簡(jiǎn)單介紹Java網(wǎng)絡(luò)編程中的HTTP請(qǐng)求
- Java網(wǎng)絡(luò)編程之簡(jiǎn)單的服務(wù)端客戶(hù)端應(yīng)用實(shí)例
- Java網(wǎng)絡(luò)編程基礎(chǔ)教程之Socket入門(mén)實(shí)例
- java網(wǎng)絡(luò)編程之socket網(wǎng)絡(luò)編程示例(服務(wù)器端/客戶(hù)端)
- java網(wǎng)絡(luò)編程之識(shí)別示例 獲取主機(jī)網(wǎng)絡(luò)接口列表
- java網(wǎng)絡(luò)編程學(xué)習(xí)java聊天程序代碼分享
- java網(wǎng)絡(luò)編程中向指定URL發(fā)送GET POST請(qǐng)求示例
- java 開(kāi)發(fā)中網(wǎng)絡(luò)編程之IP、URL詳解及實(shí)例代碼
相關(guān)文章
MyBatis寫(xiě)入Json字段以及Json字段轉(zhuǎn)對(duì)象示例詳解
這篇文章主要給大家介紹了關(guān)于MyBatis寫(xiě)入Json字段以及Json字段轉(zhuǎn)對(duì)象的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07淺談synchronized加鎖this和class的區(qū)別
synchronized 是 Java 語(yǔ)言中處理并發(fā)問(wèn)題的一種常用手段,本文主要介紹了synchronized加鎖this和class的區(qū)別,具有一定的參考價(jià)值,感興趣的可以了解一下2021-11-11java線(xiàn)程并發(fā)semaphore類(lèi)示例
Java 5.0里新加了4個(gè)協(xié)調(diào)線(xiàn)程間進(jìn)程的同步裝置,它們分別是Semaphore, CountDownLatch, CyclicBarrier和Exchanger,本例主要介紹Semaphore,Semaphore是用來(lái)管理一個(gè)資源池的工具,可以看成是個(gè)通行證2014-01-01

詳解Spring Security中權(quán)限注解的使用

Java判斷數(shù)字位數(shù)的方法總結(jié)

Java ArrayList擴(kuò)容問(wèn)題實(shí)例詳解

Spring?AOP實(shí)現(xiàn)多數(shù)據(jù)源動(dòng)態(tài)切換