成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java必知必會之socket

jackzou / 1079人閱讀

摘要:上,數(shù)據(jù)按有限大小的包傳輸,這些包成為數(shù)據(jù)報,每個數(shù)據(jù)報包含一個首部和一個有效載荷。不過,由于數(shù)據(jù)報長度有限,通常必須將數(shù)據(jù)分解為多個包,再在目的地重新組合。這兩個構造函數(shù),在返回之前會與遠程主機建立一個活動的網(wǎng)絡連接。

Internet上,數(shù)據(jù)按有限大小的包傳輸,這些包成為數(shù)據(jù)報(datagram),每個數(shù)據(jù)報包含一個首部(header)和一個有效載荷(payload)。首部包含包發(fā)送到的地址和端口、包來自的地址和端口、檢測數(shù)據(jù)是否被破壞的校驗和,以及用于保證可靠傳輸?shù)母鞣N其他管理信息。

有效載荷包含數(shù)據(jù)本身。

不過,由于數(shù)據(jù)報長度有限,通常必須將數(shù)據(jù)分解為多個包,再在目的地重新組合。也有可能一個包或多個包在傳輸中丟失或遭到破壞,需要重傳?;蛘甙鼇y序到達,需要重新排序。所有這些(將數(shù)據(jù)分解為包、生成首部、解析入站包的首部、跟蹤哪些包已經收到而哪些沒有收到等)是很繁重的工作,需要大量復雜的代碼。

Socket幫你掩蓋了這些底層細節(jié),如錯誤檢測、包大小、包分解、包重傳、網(wǎng)絡地址等。Socket允許程序員將網(wǎng)絡連接看作是另外一個可以讀寫字節(jié)的流。

Socket是兩臺主機之間的一個連接,它可以完成7個基本操作:
1)連接遠程主機
2)發(fā)送數(shù)據(jù)
3)接收數(shù)據(jù)
4)關閉連接
5)綁定端口
6)監(jiān)聽入站數(shù)據(jù)
7)在綁定端口上接受來自遠程機器的連接

一旦建立了socket連接,就可以使用輸入輸出流,這個連接是全雙工的(full-duplex),兩臺主機都可以同時發(fā)送和接收數(shù)據(jù)。

SMTP是服務器之間或郵件客戶端與服務器之間傳輸電子郵件所用的協(xié)議。

半關閉Socket:close方法同時關閉Socket的輸入流和輸出流,如果只希望關閉連接的一半(輸入/輸出),調用shutdownInput或shutdownOutput方法即可。這兩個方法并不關閉Scoket,實際上,它會調整與Socket連接的流,使它認為已經到了流的末尾。關閉輸入之后,再讀取輸入流會返回-1,關閉輸出流之后再寫入Socket則會拋出一個IOException異常。
即使半關閉了連接,或者將連接的兩半都關閉了,使用結束后還是需要關閉該Socket。shutdown只是影響了socket流,并不釋放與socket關聯(lián)的資源,如占用的端口等。

java.net.Socket是Java完成客戶端TCP操作的基礎類,它使用原生代碼與主機操作系統(tǒng)的本地TCP棧進行通信。

public Socket(String host, int port) throws UnknownHostException, IOException
public Socket(InetAddress host, int port) throws IOException

這兩個構造函數(shù),在返回之前會與遠程主機建立一個活動的網(wǎng)絡連接。port在1~65535之間。

public Socket()
public Socket(Proxy proxy)
protected Socket(SocketImpl impl)
這三個函數(shù)可以創(chuàng)建未連接的Socket。

public Socket(String host, int port, InetAddress interface, int localPort)

  throws IOException, UnknownHostException

public Socket(InetAddress host, int port, InetAddress interface, int localPort)

  throws IOException

這兩個構造函數(shù)可以用來指定從哪個接口和端口連接。

SocketAddress

SocketAddress表示一個連接端點,理論上可以用于TCP和非TCP socket。實際上只支持TCP/IP Socket。

SocketAddress主要是為了暫時的socket連接信息(如IP地址和端口)提供一個方便的存儲,即使最初的socket已斷開并被垃圾回收,這些信息也可以重用來創(chuàng)建新的Socket。

boolean connected = socket.isConnected() && ! socket.isClosed();

isConnected表示是否連接過一個遠程主機,即使socket已經關閉,因而要判斷socket是否打開著的,還要判斷是否已經關閉了。

Socket選項 1)TCP_NODELAY

設置為true,可確保包會盡可能快地發(fā)送,而不論包的大小。
正常情況下,小數(shù)據(jù)包在發(fā)送前會組合為更大的包,在發(fā)送另一個包之前,本地主機要等待遠程系統(tǒng)對前一個包的確認,這稱為Nagle算法。

Nagle算法的問題是如果遠程系統(tǒng)沒有足夠快地將確認發(fā)送回本地系統(tǒng),那么依賴于小數(shù)據(jù)量信息穩(wěn)定傳輸?shù)膽贸绦驎兟?。對于網(wǎng)絡或游戲等計算機應用程序(服務器需要實時跟蹤客戶端鼠標的移動),這個問題尤為嚴重,在一個相當慢的網(wǎng)絡中,即使簡單地打字也會由于持續(xù)的緩沖而變得太慢。設置為true,可以關閉這種緩沖模式,這樣素有包一旦就緒就會發(fā)送。

2)SO_LINGER

指定了Socket關閉時如何處理尚未發(fā)送的數(shù)據(jù)報,默認情況下,close方法將立即返回,但系統(tǒng)仍然會嘗試發(fā)送剩余的數(shù)據(jù),如果延遲時間設置為0,那么當Socket關閉時,所有未發(fā)送的數(shù)據(jù)包都將被丟棄,如果SO_LINGER打開而且延遲時間設置為任意正數(shù),close方法會阻塞指定的時間,等待發(fā)送數(shù)據(jù)和接收確認。指定時間一過,Socket關閉,所有剩余的數(shù)據(jù)都不會發(fā)送,也不會接收確認。
返回-1表示該選項被禁用,會根據(jù)需要用更多的時間發(fā)送剩余的數(shù)據(jù)。

3)SO_TIMEOUT

正常情況下,嘗試從Socket讀取數(shù)據(jù)時,read()調用會阻塞盡可能長的時間來得到足夠的字節(jié)。設置timeout確保這個調用會阻塞的時間不會超過指定的閾值,如果超出則拋異常,但是Socket仍然是連接的,可以再次嘗試肚餓去這個Socket,下一次調用可能會成功。
0表示無限超時。

4)SO_RCVBUF和SO_SNDBUF

TCP使用緩沖區(qū)來提升網(wǎng)絡性能,較大的緩沖區(qū)會提升快速連接(比如10M/s)的性能,而較慢的撥號連接利用較小的緩沖區(qū)會有更好地表現(xiàn)。

一般來講,傳輸連續(xù)的大數(shù)據(jù)塊時(在ftp和http中較為常見),可以從大緩沖區(qū)收益,而對于交互式會話的小數(shù)據(jù)量傳輸(比如telnet和很多游戲),大緩沖區(qū)則沒有多大幫助。如今128K字節(jié)已經是一個常見的默認設置。

可以達到的最大帶寬=緩沖區(qū)大小/延遲。例如,xp上,假設兩個主機之間的延遲為500ms,xp上的緩沖區(qū)大小為17520字節(jié),則帶寬=17520/0.5=273.75kb/s。這是Socket的最大速度,而不論網(wǎng)絡速度有多快。對于一個撥號連接來說,這樣的速度已經很快了。

可以通過減少延遲來提升速度,不過,延遲與網(wǎng)絡硬件有關,另外還取決于你的應用控制之外的其他一些因素。
如果把緩沖區(qū)從17520字節(jié)提升到128K,則最大帶寬會增加到2Mb/s,如果加到256K時,最大帶寬會增大到4Mb/s。

當然網(wǎng)絡本身對最大帶寬也是有限制的,如果將緩沖區(qū)設置的過高,程序會試圖以過高的速度發(fā)送和接收數(shù)據(jù),而網(wǎng)絡來不及處理,這就會導致?lián)砣?、丟包和性能下降。因此,要得到最大帶寬,需要讓緩沖區(qū)大小與連接的延遲匹配,是它稍小于網(wǎng)絡的帶寬。

可以用ping去檢測主機的延遲。

SO_RCVBUF控制用于網(wǎng)絡輸入的建議的接收緩沖區(qū)的大小,雖然可以獨立地設置接收和發(fā)送緩沖區(qū)的大小,但是實際上緩沖區(qū)通常會設置為二者中較小的一個。

Linux系統(tǒng)通常指定一個最大緩沖區(qū)大小,一般是64KB或256KB,而且不允許任何socket有更大的緩沖區(qū)。

一般情況下,如果你發(fā)送你的應用不能充分利用可用帶寬(例如,你有一個25Mb/s的Internet連接,但是數(shù)據(jù)傳輸速率僅為1.5Mb/s),那么可以試著增加緩沖區(qū)的大??;相反,如果存在丟包和擁塞現(xiàn)象,則要減少緩沖區(qū)大小。

不過,大部分情況,除非網(wǎng)絡在某個方向上負載過大,否則默認值就很合適。具體來說,現(xiàn)代操作系統(tǒng)使用TCP窗口縮放來動態(tài)調整緩沖區(qū)的大小,以適應網(wǎng)絡。

一般經驗是,除非你檢測到某個問題,否則不要進行調整。一般調整操作系統(tǒng)的最大緩沖區(qū)比在Java里頭調整單個socket的緩沖區(qū)大小效益要高。

5)SO_KEEPALIVE

如果打開這個,客戶端偶爾會通過一個空閑連接發(fā)送一個數(shù)據(jù)包(一般兩小時一次),以確保服務器沒有崩潰。如果服務器沒能響應這個包,客戶端會持續(xù)嘗試11分鐘多的時間,直到接收到響應為止。如果在12分鐘內未收到響應,則客戶端就關閉socket。如果不打開這個,不活動的客戶端可能會永遠存在下去,而不會注意到服務器是否已經崩潰。

6)OOBINLINE

TCP包括一個可以發(fā)送單字節(jié)帶外(Out Of Band,OOB)緊急數(shù)據(jù)的特性。這個數(shù)據(jù)會立即發(fā)送,此外,當接收方收到緊急數(shù)據(jù)時會得到通知,在處理其他已收到的數(shù)據(jù)之前可以選擇先處理這個緊急數(shù)據(jù)(必要時flush當前緩沖區(qū))。

Java里對應的方法是sendUrgentData

默認情況下,Java會忽略從Socket接收的緊急數(shù)據(jù),如果希望接收到正常數(shù)據(jù)中的緊急數(shù)據(jù),需要setOOBInline為true。一旦開啟,到達的任何緊急數(shù)據(jù)將以正常方式放在Socket的輸入流中等待讀取。

7)SO_REUSEADDR

一個Socket關閉時,可能不會立即釋放本地端口,尤其是當Socket關閉時若仍有一個打開的連接,就不會釋放本地端口,有時會等待一小段時間,確保接收到所有要發(fā)送到這個端口的延遲數(shù)據(jù)包,Socket關閉時這些數(shù)據(jù)包可能仍在網(wǎng)絡上傳輸,系統(tǒng)不會對接收到的延遲包做任何處理,只是希望確保這些數(shù)據(jù)不會意外地傳入綁定到同一端口的新進程。

如果使用隨機端口,則問題不大,但是如果Socket綁定到一個已知的端口,可能會有問題,因為這會阻止所有其他Socket同時使用這個端口,如果開啟這個參數(shù)(默認是關閉),則允許另外一個Socket綁定到這個端口,即使此時仍有可能存在前一個Socket未接收的數(shù)據(jù)。

setReuseAddress必須在綁定新Socket之前調用。只有之前連接的Socket和重用老地址的新Scoket的這個值都設置為true,才能生效。

8)IP_TOS

不同類型的Internet服務對性能有不同的需求,比如視頻要求相對較高的帶寬和較短的延遲,而email可以通過較低帶寬的連接傳遞等。
服務類型存儲在IP首部中的一個名為IP_TOS的8位字段中。在Java中使用setTrafficClass來設定,java里頭是0-255,但是TCP首部要求是8位,因而只能使用int的低字節(jié)。

Socket異常
1)BindException,端口被占用或沒有權限使用該端口
2)ConnectException,連接遠程主機被拒絕(遠程主機忙或者沒有進程監(jiān)聽該端口)
3)NoRouteToHostException,連接超時
4)ProtocolException,違反TCP/IP規(guī)定

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/65923.html

相關文章

  • java必知會之SecureSocket

    SSL,Secure Sockets Layer,安全Socket層TLS,Transport Layer Security,傳輸層安全協(xié)議 package network.secure; import java.io.*; import javax.net.ssl.*; public class HTTPSClient { public static void main(Strin...

    kidsamong 評論0 收藏0
  • java必知會之ServerSocket

    摘要:單個請求范圍之外的異??赡軙P閉服務器??蛻舳丝赡艹瑫r或崩潰,用戶可能取消事務,網(wǎng)絡可能在流量高峰期間癱瘓,黑客可能發(fā)動拒絕服務攻擊。如果默認長度不夠大,一些的構造函數(shù)還允許改變這個隊列的長度,不能不能超過操作系統(tǒng)支持的最大值。 ServerSocket的生命周期 一個ServerSocket的基本生命周期:1)使用一個ServerSocket構造函數(shù)在一個特定端口創(chuàng)建一個新的Serv...

    chinafgj 評論0 收藏0

發(fā)表評論

0條評論

jackzou

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<