UDP協議與TCP/IP協議

一、UDP與TCP協議

UDP(User Datagram Protocol)協議是無面向連接的、不可靠的、無序的、無流量控制的傳輸層協議,UDP發送的每個數據報是記錄型的數據報,所謂的記錄型數據報就是接收進程可以識別接收到的數據報的記錄邊界。TCP(Transmission Control Protocol 傳輸控制協議)協議是面向連接的、可靠的、有序的、擁有流量控制的傳輸層協議,它是字節流的協議,無記錄邊界。

1.記錄與字節流

UDP協議:發送進程在發送每個數據報的時候並不等待多個數據報集中在一起以一個較大數據報發送出去,而是立即發送出去,它是記錄型的協議。並且接收進程每次通過readrecv……獲得的數據報必定是發送進程所發送的那個數據報。不可能是多個數據報,接收進程可以識別到發送進程所發送的每個數據報的記錄邊界。

TCP協議:發送進程在發送每個數據報的時候在內核處理過程中有可能並不立即發送出去,而是會將多個數據報集中在一起以一個較大的數據報來發送,它是字節流的協議。而接收進程每次通過read來讀取發送進程發送過來的數據報並不一定是發送進程原先發送數據報,接收進程無法識別每個數據報的記錄邊界,所以TCP協議就是字節流的、無記錄邊界的協議。

例如:QQ聊天所用到的協議就應該是有記錄邊界的,聊天過程中是以“消息”爲單位,消息可以看成一個記錄,所以QQ聊天協議採取UDP協議而不是TCP協議。

 

2.有序與無序

UDP協議:發送進程所發送的每個數據報並不按照原先發送的順序到達接收進程,有可能早發送的數據報較後到達接收進程。因爲數據報在經過中間路徑的傳送時會因爲各個數據報傳送的路徑不同或者其它原因而造成這些數據報到達的順序不同,UDP協議是無序的傳輸協議。所以爲了使基於UDP協議的應用程序有序,必須在應用程序中設置序號、確認機制來使其有序。

TCP協議:有序協議,有超時、序號、重傳、確認機制。

例如:FTP協議是用於傳送文件的協議,爲了確保在傳送文件內容的時候,傳送的每個數據報協議有序接收,所以FTP協議是基於TCP協議。 

那爲什麼FTP協議不是是基於UDP協議?因爲爲了保證有序,FTP協議中引入了確認、序號字段。

這裏還有一個問題,FTP協議中的控制連接傳送的內容好像都是基於消息形式,客戶端在控制連接上發出一個請求消息,服務器端返回一個請求結果消息,感覺應該FTP控制連接採取UDP協議,爲什麼採取TCP協議?因爲控制連接上是交互式的消息傳送,客戶端在發送一個請求之後,在服務器端的響應消息未到達之前,客戶端是不會發送第二個請求消息,所以不用擔心這兩個請求消息會疊加在一起。也就是對於交互式的消息傳遞也可以採用TCP協議。

 

3.流量控制

UDP協議:沒有流量控制機制,如果發送進程發送數據報塞滿了接收進程的接收緩衝區,就會丟棄數據報。出現這種情況,UDP協議不會通知發送進程減緩數據的發送速率。

TCP協議:擁有流量控制。


4.客戶端通信過程比較

4.1 客戶端的連接過程比較

UDP協議在創建端口之後,可以同多個服務器端建立通信,而TCP協議只能與一個服務器端建立通信,TCP不允許目的地址是廣播或多播地址,UDP允許。UDP協議客戶端同服務器端的通信關係可以是一對多的關係,而TCP協議只能是一對一的關係。

通過UDP協議可以給同一個端口指定多次connect操作,而TCP協議不可以,TCP只能指定一次connect操作。UDP協議指定第二次connect操作之後會先斷口第一次的連接,然後建立第二次的連接

4.2 服務器端的連接過程比較

對於UDP協議客戶端與服務器端沒有什麼本質的區別,每個UDP協議的客戶端也是服務器端。TCP協議就不同了,TCP協議必須通過listen 來申請監聽,然後通過accept來接收一個客戶端的連接,當接收客戶端的連接會再創建一個單獨的端口用來同客戶端之間進行數據通信,也就是說服務器端由一個單獨的監聽端口負責監聽客戶端的連接請求,當接收到一個來自客戶端的連接請求之後,服務器會另外創建一個端口負責同客戶端之間進行連接通信。


5.TCP與UDP應用:

1、TCP在網絡通信上有極強的生命力,例如遠程連接(Telnet)和文件傳輸(FTP)都需要不定長度的數據被可靠地傳輸。但是可靠的傳輸是要付出代價的,對數據內容正確性的檢驗必然佔用計算機的處理時間和網絡的帶寬,因此TCP傳輸的效率不如UDP高。

 2,UDP操作簡單,而且僅需要較少的監護,因此通常用於局域網高可靠性的分散系統中client/server應用程序。例如視頻會議系統,並不要求音頻視頻數據絕對的正確,只要保證連貫性就可以了,這種情況下顯然使用UDP會更合理一些。

二、Socket是什麼

  Socket通常也稱作"套接字",用於描述IP地址和端口,是一個通信鏈的句柄。網絡上的兩個程序通過一個雙向的通訊管道連接實現數據的交換,這個雙向鏈路的一端稱爲一個Socket,一個Socket由一個IP地址和一個端口號唯一確定應用程序通常通過"套接字"向網絡發出請求或者應答網絡請求。 Socket是TCP/IP協議的一個十分流行的編程界面,但是,Socket所支持的協議種類也不光TCP/IP一種,因此兩者之間是沒有必然聯繫的。在Java環境下,Socket編程主要是指基於TCP/IP協議的網絡編程。

  Socket通訊過程:服務端監聽某個端口是否有連接請求,客戶端向服務端發送連接請求,服務端收到連接請求向客戶端發出接收消息,這樣一個連接就建立起來了。客戶端和服務端都可以相互發送消息與對方進行通訊。

  Socket的基本工作過程包含以下四個步驟:

  1、創建Socket;

  2、打開連接到Socket的輸入輸出流;

  3、按照一定的協議對Socket進行讀寫操作;

  4、關閉Socket。

三、Java中的Socket

  在java.net包下有兩個類:Socket和ServerSocket。ServerSocket用於服務器端,Socket是建立網絡連接時使用的。在連接成功時,應用程序兩端都會產生一個Socket實例,操作這個實例,完成所需的會話。對於一個網絡連接來說,套接字是平等的,並沒有差別,不因爲在服務器端或在客戶端而產生不同級別。不管是Socket還是ServerSocket它們的工作都是通過SocketImpl類及其子類完成的。

列出幾個常用的構造方法:

Socket(InetAddress address,int port);//創建一個流套接字並將其連接到指定 IP 地址的指定端口號

Socket(String host,int port);//創建一個流套接字並將其連接到指定主機上的指定端口號

Socket(InetAddress address,int port, InetAddress localAddr,int localPort);//創建一個套接字並將其連接到指定遠程地址上的指定遠程端口

Socket(String host,int port, InetAddress localAddr,int localPort);//創建一個套接字並將其連接到指定遠程主機上的指定遠程端口

Socket(SocketImpl impl);//使用用戶指定的 SocketImpl 創建一個未連接 Socket

 

ServerSocket(int port);//創建綁定到特定端口的服務器套接字

ServerSocket(int port,int backlog);//利用指定的 backlog 創建服務器套接字並將其綁定到指定的本地端口號

ServerSocket(int port,int backlog, InetAddress bindAddr);//使用指定的端口、偵聽 backlog 和要綁定到的本地 IP地址創建服務器

 

構造方法的參數中,address、host和port分別是雙向連接中另一方的IP地址、主機名和端 口號,stream指明socket是流socket還是數據報socket,localPort表示本地主機的端口號,localAddr和bindAddr是本地機器的地址(ServerSocket的主機地址),impl是socket的父類,既可以用來創建serverSocket又可以用來創建Socket。count則表示服務端所能支持的最大連接數。

注意:必須小心選擇端口號。每一個端口提供一種特定的服務,只有給出正確的端口,才 能獲得相應的服務。0~1023的端口號爲系統所保留,例如http服務的端口號爲80,telnet服務的端口號爲21,ftp服務的端口號爲23, 所以我們在選擇端口號時,最好選擇一個大於1023的數以防止發生衝突。

幾個重要的Socke方法:

1

2

3

public InputStream getInputStream();//方法獲得網絡連接輸入,同時返回一個IutputStream對象實例

public OutputStream getOutputStream();//方法連接的另一端將得到輸入,同時返回一個OutputStream對象實例

public Socket accept();//用於產生"阻塞",直到接受到一個連接,並且返回一個客戶端的Socket對象實例。


"阻塞"是一個術語,它使程序運行暫時"停留"在這個地方,直到一個會話產生,然後程序繼續;通常"阻塞"是由循環產生的。

注意:其中getInputStream和getOutputStream方法均會產生一個IOException,它必須被捕獲,因爲它們返回的流對象,通常都會被另一個流對象使用。


這篇文章沒有涉及到如何使用java來實現網絡編程。如果想知道java是如何實現的,請關注我的另一篇文章:Java實現的網絡編程——基礎篇http://blog.csdn.net/lulei1217/article/details/50266125

發佈了45 篇原創文章 · 獲贊 31 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章