java---Socket编程出现的异常种类
.java.net.SocketTimeoutException.這個(gè)異常比較常見(jiàn),socket超時(shí)。一般有2個(gè)地方會(huì)拋出這個(gè),一個(gè)是connect的時(shí)候,這個(gè)超時(shí)參數(shù)由connect(SocketAddress endpoint,int timeout)中的后者來(lái)決定,還有就是setSoTimeout(int timeout),這個(gè)是設(shè)定讀取的超時(shí)時(shí)間。它們?cè)O(shè)置成0均表示無(wú)限大。
2.java.net.BindException:Address already in use: JVM_Bind。該異常發(fā)生在服務(wù)器端進(jìn)行new ServerSocket(port) 或者socket.bind(SocketAddress bindpoint)操作時(shí)。
原因:與port一樣的一個(gè)端口已經(jīng)被啟動(dòng),并進(jìn)行監(jiān)聽(tīng)。此時(shí)用netstat –an命令,可以看到一個(gè)Listending狀態(tài)的端口。只需要找一個(gè)沒(méi)有被占用的端口就能解決這個(gè)問(wèn)題。
?
3.java.net.ConnectException: Connection refused: connect。該異常發(fā)生在客戶端進(jìn)行new Socket(ip, port)或者socket.connect(address,timeout)操作時(shí).
原因:指定ip地址的機(jī)器不能找到(也就是說(shuō)從當(dāng)前機(jī)器不存在到指定ip路由),或者是該ip存在,但找不到指定的端口進(jìn)行監(jiān)聽(tīng)。應(yīng)該首先檢查客戶端的ip和port是否寫錯(cuò)了,假如正確則從客戶端ping一下服務(wù)器看是否能ping通,假如能ping通(服務(wù)服務(wù)器端把ping禁掉則需要另外的辦法),則看在服務(wù)器端的監(jiān)聽(tīng)指定端口的程序是否啟動(dòng)。
?
4.java.net.SocketException: Socket is closed,該異常在客戶端和服務(wù)器均可能發(fā)生。異常的原因是己方主動(dòng)關(guān)閉了連接后(調(diào)用了Socket的close方法)再對(duì)網(wǎng)絡(luò)連接進(jìn)行讀寫操作。
?
5.java.net.SocketException: Connection reset或者Connect reset by peer:Socket write error。該異常在客戶端和服務(wù)器端均有可能發(fā)生,引起該異常的原因有兩個(gè),第一個(gè)就是假如一端的Socket被關(guān)閉(或主動(dòng)關(guān)閉或者因?yàn)楫惓M顺龆鸬年P(guān)閉),另一端仍發(fā)送數(shù)據(jù),發(fā)送的第一個(gè)數(shù)據(jù)包引發(fā)該異常(Connect reset by peer)。另一個(gè)是一端退出,但退出時(shí)并未關(guān)閉該連接,另一端假如在從連接中讀數(shù)據(jù)則拋出該異常(Connection reset)。簡(jiǎn)單的說(shuō)就是在連接斷開(kāi)后的讀和寫操作引起的。
對(duì)于服務(wù)器,一般的原因可以認(rèn)為:
a) 服務(wù)器的并發(fā)連接數(shù)超過(guò)了其承載量,服務(wù)器會(huì)將其中一些連接主動(dòng)Down掉.
b) 在數(shù)據(jù)傳輸?shù)倪^(guò)程中,瀏覽器或者接收客戶端關(guān)閉了,而服務(wù)端還在向客戶端發(fā)送數(shù)據(jù)。
?
6.java.net.SocketException: Broken pipe。該異常在客戶端和服務(wù)器均有可能發(fā)生。在拋出SocketExcepton:Connect reset by peer:Socket write error后,假如再繼續(xù)寫數(shù)據(jù)則拋出該異常。前兩個(gè)異常的解決方法是首先確保程序退出前關(guān)閉所有的網(wǎng)絡(luò)連接,其次是要檢測(cè)對(duì)方的關(guān)閉連接操作,發(fā)現(xiàn)對(duì)方關(guān)閉連接后自己也要關(guān)閉該連接。
對(duì)于4和5這兩種情況的異常,需要特別注意連接的維護(hù)。在短連接情況下還好,如果是長(zhǎng)連接情況,對(duì)于連接狀態(tài)的維護(hù)不當(dāng),則非常容易出現(xiàn)異常。基本上對(duì)長(zhǎng)連接需要做的就是:
a) 檢測(cè)對(duì)方的主動(dòng)斷連(對(duì)方調(diào)用了Socket的close方法)。因?yàn)閷?duì)方主動(dòng)斷連,另一方如果在進(jìn)行讀操作,則此時(shí)的返回值是-1。所以一旦檢測(cè)到對(duì)方斷連,則主動(dòng)關(guān)閉己方的連接(調(diào)用Socket的close方法)。
b) 檢測(cè)對(duì)方的宕機(jī)、異常退出及網(wǎng)絡(luò)不通,一般做法都是心跳檢測(cè)。雙方周期性的發(fā)送數(shù)據(jù)給對(duì)方,同時(shí)也從對(duì)方接收“心跳數(shù)據(jù)”,如果連續(xù)幾個(gè)周期都沒(méi)有收到對(duì)方心跳,則可以判斷對(duì)方或者宕機(jī)或者異常退出或者網(wǎng)絡(luò)不通,此時(shí)也需要主動(dòng)關(guān)閉己方連接;如果是客戶端可在延遲一定時(shí)間后重新發(fā)起連接。雖然Socket有一個(gè)keep alive選項(xiàng)來(lái)維護(hù)連接,如果用該選項(xiàng),一般需要兩個(gè)小時(shí)才能發(fā)現(xiàn)對(duì)方的宕機(jī)、異常退出及網(wǎng)絡(luò)不通。
7.java.net.SocketException: Too many open files
原因: 操作系統(tǒng)的中打開(kāi)文件的最大句柄數(shù)受限所致,常常發(fā)生在很多個(gè)并發(fā)用戶訪問(wèn)服務(wù)器的時(shí)候。因?yàn)闉榱藞?zhí)行每個(gè)用戶的應(yīng)用服務(wù)器都要加載很多文件(new一個(gè)socket就需要一個(gè)文件句柄),這就會(huì)導(dǎo)致打開(kāi)文件的句柄的缺乏。
解決方式:
a) 盡量把類打成jar包,因?yàn)橐粋€(gè)jar包只消耗一個(gè)文件句柄,如果不打包,一個(gè)類就消耗一個(gè)文件句柄。?
b)?Java的GC不能關(guān)閉網(wǎng)絡(luò)連接打開(kāi)的文件句柄,如果沒(méi)有執(zhí)行close()則文件句柄將一直存在,而不能被關(guān)閉。也可以考慮設(shè)置socket的最大打開(kāi)數(shù)來(lái)控制這個(gè)問(wèn)題。對(duì)操作系統(tǒng)做相關(guān)的設(shè)置,增加最大文件句柄數(shù)量。ulimit -a可以查看系統(tǒng)目前資源限制,ulimit -n 10240則可以修改,這個(gè)修改只對(duì)當(dāng)前窗口有效。
?
轉(zhuǎn)載于:https://www.cnblogs.com/w-wfy/p/6415840.html
總結(jié)
以上是生活随笔為你收集整理的java---Socket编程出现的异常种类的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 013. MVC5过滤器
- 下一篇: xcode中用pods管理第三方库转