亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

Java必知必會(huì)之socket

jackzou / 1150人閱讀

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

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

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

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

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

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

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

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

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

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

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

這兩個(gè)構(gòu)造函數(shù),在返回之前會(huì)與遠(yuǎn)程主機(jī)建立一個(gè)活動(dòng)的網(wǎng)絡(luò)連接。port在1~65535之間。

public Socket()
public Socket(Proxy proxy)
protected Socket(SocketImpl impl)
這三個(gè)函數(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

這兩個(gè)構(gòu)造函數(shù)可以用來(lái)指定從哪個(gè)接口和端口連接。

SocketAddress

SocketAddress表示一個(gè)連接端點(diǎn),理論上可以用于TCP和非TCP socket。實(shí)際上只支持TCP/IP Socket。

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

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

isConnected表示是否連接過(guò)一個(gè)遠(yuǎn)程主機(jī),即使socket已經(jīng)關(guān)閉,因而要判斷socket是否打開(kāi)著的,還要判斷是否已經(jīng)關(guān)閉了。

Socket選項(xiàng) 1)TCP_NODELAY

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

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

2)SO_LINGER

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

3)SO_TIMEOUT

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

4)SO_RCVBUF和SO_SNDBUF

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

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

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

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

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

可以用ping去檢測(cè)主機(jī)的延遲。

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

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

一般情況下,如果你發(fā)送你的應(yīng)用不能充分利用可用帶寬(例如,你有一個(gè)25Mb/s的Internet連接,但是數(shù)據(jù)傳輸速率僅為1.5Mb/s),那么可以試著增加緩沖區(qū)的大?。幌喾矗绻嬖趤G包和擁塞現(xiàn)象,則要減少緩沖區(qū)大小。

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

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

5)SO_KEEPALIVE

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

6)OOBINLINE

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

Java里對(duì)應(yīng)的方法是sendUrgentData

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

7)SO_REUSEADDR

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

如果使用隨機(jī)端口,則問(wèn)題不大,但是如果Socket綁定到一個(gè)已知的端口,可能會(huì)有問(wèn)題,因?yàn)檫@會(huì)阻止所有其他Socket同時(shí)使用這個(gè)端口,如果開(kāi)啟這個(gè)參數(shù)(默認(rèn)是關(guān)閉),則允許另外一個(gè)Socket綁定到這個(gè)端口,即使此時(shí)仍有可能存在前一個(gè)Socket未接收的數(shù)據(jù)。

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

8)IP_TOS

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

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

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/65923.html

相關(guān)文章

  • java必知會(huì)之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 評(píng)論0 收藏0
  • java必知會(huì)之ServerSocket

    摘要:?jiǎn)蝹€(gè)請(qǐng)求范圍之外的異??赡軙?huì)關(guān)閉服務(wù)器。客戶(hù)端可能超時(shí)或崩潰,用戶(hù)可能取消事務(wù),網(wǎng)絡(luò)可能在流量高峰期間癱瘓,黑客可能發(fā)動(dòng)拒絕服務(wù)攻擊。如果默認(rèn)長(zhǎng)度不夠大,一些的構(gòu)造函數(shù)還允許改變這個(gè)隊(duì)列的長(zhǎng)度,不能不能超過(guò)操作系統(tǒng)支持的最大值。 ServerSocket的生命周期 一個(gè)ServerSocket的基本生命周期:1)使用一個(gè)ServerSocket構(gòu)造函數(shù)在一個(gè)特定端口創(chuàng)建一個(gè)新的Serv...

    chinafgj 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

jackzou

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<