1. 程式人生 > >【Java TCP/IP Socket程式設計】----進階----注意點

【Java TCP/IP Socket程式設計】----進階----注意點

1.廣播和多播:TCP套接字中客戶端只能接收和傳送指定伺服器端過來的資料,這種一對一的通訊方式叫單播,而UDP套接字可以容許一個傳送端和多個接收端情況,一對多的型別有:廣播和多播。

      1)廣播:本地網路中所有的主機都會接收到一份資料副本。IPv4廣播地址(255.255.255.255)將訊息傳送到同一個廣播網路中上的所有主機,本地廣播資訊不回被路由器轉發。廣播不能使用連線,有些作業系統不支援普通使用者進行廣播操作。

      2)多播:網路只分發資料給想要接收資料的多播地址的主機。一個多播地址指示了一組接收者,IP協議的設計者為多播分配了一定範圍的地址空間,IPv4中多播地址是224.0.0.0到239.255.255.255,IPv6中多播地址是FF開頭的地址。多播報文會初始化一個TTL值(Time To Live,生命週期),當存在路由器轉發便會減1,TTL值為0時,丟棄該資料報文。

2.Keep-Alive:TCP協議提供了一種Keep-alive機制,傳送端和接收端一段時間內沒有資料交換時,傳送端會向終端傳送探測訊息,終端如果處於活躍狀態會回覆一個確認訊息。幾次嘗試後依然沒有收到終端訊息,則會終止傳送探測訊息,關閉套接字,下次IO操作時會丟擲異常。

3.傳送和接收快取區的大小:當建立了Socket或者DatagramSocket例項的時候,作業系統就必須為其分配快取區以存放接收的和要傳送的資料。方法setReceiveBufferSize(int size)和setSendBufferSize(int size);

4.超時:很多IO操作如果不能立即完成就會阻塞等待,讀操作會阻塞等待直到至少一個位元組可讀;接收操作將阻塞等待直到成功建立連線。通過呼叫setSoTimeout()方法設定讀,接收資料以及accept()方法的最長阻塞時間。

5.地址重用:某些情況下,希望能將多個套接字繫結到同一個套接字地址,對於UDP多播情況,同一個主機上可能有多個應用程式加入相同的多播組。對於TCP來說,當一個連線關閉後,通訊的一端必須在“Time-Wait”狀態上等一段時間,以對傳輸途中丟失的資料包進行清理,但通訊終端可能無法等待Time-Wait結束。這兩種情況需要能夠與正在使用的地址進行繫結的能力,實現地址的重用。

6.消除緩衝延遲:TCP協議將資料快取起來直到足夠多時一次傳送,以避免傳送過小的資料包而浪費網路資源。雖然這個功能有利於網路,但是應用程式可能對所造成的緩衝延遲無法容忍,可以禁用快取功能,呼叫方法setTcpNoDelay(true).

7.緊急資料:TCP協議中包含了緊急資料的概念,如果需要傳送一條緊急資料,但是前面已經有很多其他資料,要求能夠繞過這些常規資料(頻道外資料)。但Java中緊急資料幾乎沒有什麼用,因為常規資料與緊急資料順序混在一起,接收者無法區別。

8關閉後停留:呼叫套接字的close()方法後,即使套接字的緩衝區中還存在沒有傳送的資料,它也會立即返回。這樣不傳送完所有數可能導致的問題是主機將在後面的某個時刻發生故障。其實可以選擇然close()方法“停留”或者阻塞一段時間,直到傳送所有資料都已經發送並確認,或者發生了超時。呼叫方法setSoLinger(boolean on, int linger)。

9.廣播許可:一些作業系統要求顯式地對廣播許可進行請求,可以對廣播許可進行控制。呼叫方法,setBroadcast(true),true表示允許廣播

10.通訊等級:有的網路對滿足服務條件的資料報提供了增強的服務或者額外的保險。一個數據報的通訊登記由資料包在網路中傳輸時其內部的一個值來指定。但是通訊等級會收到網路提供者的限制,不能保證這項功能可用。(方法setTrafficClass(int tc))

11.基於效能的協議選擇:TCP協議不是套接字唯一可選的協議,Java允許開發者根據不同的效能特徵對於應用程式的重要程式,為具體實現給出建議,底層網路系統可能會根據這些建議,在一組能夠提供同等的資料流服務,同時有具有不同的效能特徵的不同協議中做出選擇。方法setPerformancePreferences(int connectionTime,int latency,int bandwidth)設定連線時間,延遲和頻寬,底層會根據這些引數設定選擇合適的協議。

12.關閉連線:網路協議通常明確指定了誰來關閉連線。但直接呼叫Socket的close()將會同時終止輸出和輸入兩個方向的資料流,如客戶端傳送完資料後呼叫close()方法就會導致接收不到資料,需要一種方法來告訴連線的另一端我已經發送完所有資料,並且保持能夠接收資料的能力。套接字裡面就提供了這樣的功能,Socket類的shutdonwInput()和shutdownOutput()方法能夠將輸入輸出流單獨關閉。

      1)呼叫shutdownInput()後,套接字的輸入流將無法使用,任何沒有傳送的資料都將被丟棄,任何想從套接字的輸入流讀取資料的操作都將返回-1。

      2)呼叫shutdownOutput()方法時,套接字的輸出流將無法再發送資料,任何嘗試向輸出流寫資料的操作都將丟擲異常IOException異常。