JAVA基礎——網絡編程之網絡連接

1、網絡編程基本概念

1.OSI與TCP/IP體系模型

 

2.IP和端口

解決了文章最開始提到的定位的問題。java

IP在互聯網中能惟一標識一臺計算機,是每一臺計算機的惟一標識(身份證);網絡編程是和遠程計算機的通訊,因此必須先能定位到遠程計算機;IP幫助解決此問題;一臺計算機中可能有不少進程,具體和哪個進程進行通訊,這就得靠端口來識別;編程

IP和端口能惟必定位到須要通訊的進程。這裏的IP表示地址,區別於IP協議。在OSI體系仍是TCP/IP體系中,IP協議位於網際層,來封裝IP地址到報文中。 數組

 

3.TCP和UDP協議

TCPTranfer Control Protocol的簡稱,是一種面向鏈接的保證可靠傳輸的協議。經過TCP協議傳輸,獲得的是一個順序的無差錯的數據流。發送方和接收方的成對的兩個socket之間必須創建鏈接,以便在TCP協議的基礎上進行通訊,當一個socket(一般都是server socket)等待創建鏈接時,另外一個socket能夠要求進行鏈接,一旦這兩個socket鏈接起來,它們就能夠進行雙向數據傳輸,雙方均可以進行發送或接收操做。網絡

UDPUser Datagram Protocol的簡稱,是一種無鏈接的協議,每一個數據報都是一個獨立的信息,包括完整的源地址或目的地址,它在網絡上以任何可能的路徑傳往目的地,所以可否到達目的地,到達目的地的時間以及內容的正確性都是不能被保證的。app

比較:socket

UDP:編碼

  1. 每一個數據報中都給出了完整的地址信息,所以無須要創建發送方和接收方的鏈接。
  2. UDP傳輸數據時是有大小限制的,每一個被傳輸的數據報必須限定在64KB以內。
  3. UDP是一個不可靠的協議,發送方所發送的數據報並不必定以相同的次序到達接收方

TCP:url

  1. 面向鏈接的協議,在socket之間進行數據傳輸以前必然要創建鏈接,因此在TCP中須要鏈接時間。
  2. TCP傳輸數據大小限制,一旦鏈接創建起來,雙方的socket就能夠按統一的格式傳輸大的數據。
  3. TCP是一個可靠的協議,它確保接收方徹底正確地獲取發送方所發送的所有數據。

數據楨:spa

 

應用:.net

  • TCP在網絡通訊上有極強的生命力,例如遠程鏈接(Telnet)和文件傳輸(FTP)都須要不定長度的數據被可靠地傳輸。可是可靠的傳輸是要付出代價的,對數據內容正確性的檢驗必然佔用計算機的處理時間和網絡的帶寬,所以TCP傳輸的效率不如UDP高。
  • UDP操做簡單,並且僅須要較少的監護,所以一般用於局域網高可靠性的分散系統中client/server應用程序。例如視頻會議系統,並不要求音頻視頻數據絕對的正確,只要保證連貫性就能夠了,這種狀況下顯然使用UDP會更合理一些。

 

4.Socket

Socket是網絡驅動層提供給應用程序編程接口和一種機制。咱們能夠把 Socket 比喻成是一個港口碼頭。應用程序只要把貨物放到港口碼頭上,就算完成了貨物的運送。對於接收方應用程序也要建立一個港口碼頭,只須要等待貨物到達碼頭後將貨物取走。

Socket 是在應用程序中建立的,它是經過一種綁定機制與驅動程序創建關係,告訴本身所對應的 IP 和 Port。在網絡上傳輸的每個數據幀,必須包含發送者的 IP 地址和端口號。建立完 Socket 之後,應用程序寫入到 Socket 的數據,由 Socket 交給驅動程序向網絡上發送數據,計算機從網絡上收到與某個 Socket 綁定的 IP 和 Port 相關的數據後,由驅動程序再交給 Socket ,應用程序就能夠從這個 Socket 中讀取接收到的數據。網絡應用程序就是這樣經過 Socket 發送和接收的。

Socket數據發送過程:

 

Socket數據接收過程:

 

5.經常使用應用層協議

應用層協議是爲了解決某一類應用問題,而問題的解決又每每是經過位於不一樣主機中的多個應用進程之間的通訊和協同工做來完成的。應用層的具體內容就是規定應用進程在通訊時所遵循的協議。

 

2、Java網絡編程經常使用類

1.InteAddress類

Java中的InetAddress是一個表明IP地址的封裝。IP地址能夠由字節數組和字符串來分別表示,InetAddress將IP地址以對象的形式進行封裝,能夠更方便的操做和獲取其屬性。InetAddress沒有構造方法,能夠經過兩個靜態方法得到它的對象。

複製代碼
    //根據主機名來獲取對應的InetAddress實例 InetAddress ip = InetAddress.getByName("www.baidu.com"); //判斷是否可達 System.out.println("baidu是否可達:" + ip.isReachable(2000)); //獲取該InetAddress實例的IP字符串 System.out.println(ip.getHostAddress()); //根據原始IP地址(字節數組形式)來獲取對應的InetAddress實例 InetAddress local = InetAddress.getByAddress(new byte[]{127,0,0,1}); System.out.println("本機是否可達:" + local.isReachable(5000)); //獲取該InetAddress實例對應的全限定域名 System.out.println(local.getCanonicalHostName());
複製代碼
 

2.URL和URLConnection類

網絡中的URL(Uniform Resource Locator)是統一資源定位符的簡稱。它表示Internet上某一資源的地址。經過URL咱們能夠訪問Internet上的各類網絡資源,好比最多見的WWW,FTP站點。 URL能夠被認爲是指向互聯網資源的「指針」,經過URL能夠得到互聯網資源相關信息,包括得到URL的InputStream對象獲取資源的信息,以及一個到URL所引用遠程對象的鏈接URLConnection。 URLConnection對象能夠向所表明的URL發送請求和讀取URL的資源。一般,建立一個和URL的鏈接,須要以下幾個步驟:

  1. 建立URL對象,並經過調用openConnection方法得到URLConnection對象;
  2. 設置URLConnection參數和普通請求屬性;
  3. 向遠程資源發送請求;
  4. 遠程資源變爲可用,程序能夠訪問遠程資源的頭字段和經過輸入流來讀取遠程資源返回的信息。

這裏須要重點討論一下第三步:若是隻是發送GET方式請求,使用connect方法創建和遠程資源的鏈接便可;若是是須要發送POST方式的請求,則須要獲取URLConnection對象所對應的輸出流來發送請求。這裏須要注意的是,因爲GET方法的參數傳遞方式是將參數顯式追加在地址後面,那麼在構造URL對象時的參數就應當是包含了參數的完整URL地址,而在得到了URLConnection對象以後,就直接調用connect方法便可發送請求。而POST方法傳遞參數時僅僅須要頁面URL,而參數經過須要經過輸出流來傳遞。另外還須要設置頭字段。如下是兩種方式的代碼:

複製代碼
 //1. 向指定URL發送GET方法的請求 String urlName = url + "?" + param; URL realUrl = new URL(urlName); //打開和URL之間的鏈接 URLConnection conn = realUrl.openConnection(); //設置通用的請求屬性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"); //創建實際的鏈接 conn.connect();  //2. 向指定URL發送POST方法的請求 URL realUrl = new URL(url);  //打開和URL之間的鏈接 URLConnection conn = realUrl.openConnection(); //設置通用的請求屬性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"); //發送POST請求必須設置以下兩行 conn.setDoOutput(true); conn.setDoInput(true); //獲取URLConnection對象對應的輸出流 out = new PrintWriter(conn.getOutputStream()); //發送請求參數 out.print(param);
複製代碼
 

3.URLDecoder和URLEncoder

這兩個類能夠別用於將application/x-www-form-urlencoded MIME類型的字符串轉換爲普通字符串,將普通字符串轉換爲這類特殊型的字符串。使用URLDecoder類的靜態方法decode()用於解碼,URLEncoder類的靜態方法encode()用於編碼。具體使用方法以下:

//將application/x-www-form-urlencoded字符串轉換成普通字符串  String keyWord = URLDecoder.decode("%E6%9D%8E%E5%88%9A+j2ee", "UTF-8"); System.out.println(keyWord); //將普通字符串轉換成 application/x-www-form-urlencoded字符串  String urlStr = URLEncoder.encode( "ROR敏捷開發最佳指南" , "GBK"); System.out.println(urlStr);
 

4.Socket和ServerSocket類

網絡上的兩個程序經過一個雙向的通信鏈接實現數據的交換,這個雙向鏈路的一端稱爲一個Socket。Socket一般用來實現客戶方和服務方的鏈接。Socket是TCP/IP協議的一個十分流行的編程界面,一個Socket由一個IP地址和一個端口號惟一肯定。 可是,Socket所支持的協議種類也不光TCP/IP一種,所以二者之間是沒有必然聯繫的。在Java環境下,Socket編程主要是指基於TCP/IP協議的網絡編程。 Server端Listen(監聽)某個端口是否有鏈接請求,Client端向Server端發出Connect(鏈接)請求,Server端向Client端發回Accept(接受)消息。一個鏈接就創建起來了。Server端和Client端均可以經過Send,Write等方法與對方通訊。 TCP Socket的通訊過程以下圖:

 

5.DatagramSocket類

UDP協議是一種不可靠的網絡協議,它在通信實例的兩端個創建一個Socket,但這兩個Socket之間並無虛擬鏈路,這兩個Socket只是發送和接受數據報的對象。 包java.net中提供了兩個類DatagramSocketDatagramPacket用來支持數據報通訊,DatagramSocket用於在程序之間創建傳送數據報的通訊鏈接, DatagramPacket則用來表示一個數據報。 DatagramSocket的構造方法:

DatagramSocket(); DatagramSocket(int prot); DatagramSocket(int port, InetAddress laddr);

其中,port指明socket所使用的端口號,若是未指明端口號,則把socket鏈接到本地主機上一個可用的端口。laddr指明一個可用的本地地址。給出端口號時要保證不發生端口衝突,不然會生成SocketException類例外。注意:上述的兩個構造方法都聲明拋棄非運行時例外SocketException,程序中必須進行處理,或者捕獲、或者聲明拋棄。 用數據報方式編寫client/server程序時,不管在客戶方仍是服務方,首先都要創建一個DatagramSocket對象,用來接收或發送數據報,而後使用DatagramPacket類對象做爲傳輸數據的載體。

3、總結

  • 網絡編程的核心是IP、端口、協議三大元素
  • 網絡編程的本質是進程間通訊
  • 網絡編程的2個主要問題:1是定位主機,2是數據傳輸
相關文章
相關標籤/搜索