關於Socket踩過的一些坑


Socket學習文檔   http://developer.51cto.com/developer/javabook/images/3.pdf

1.socket.shutdownOutput();

文檔解釋:

Disables the output stream for this socket. For a TCP socket, any previously written data will be sent followed by TCP's normal connection termination sequence. If you write to a socket output stream after invoking shutdownOutput() on the socket, the stream will throw an IOException.
if an I/O error occurs when shutting down this

具體可以參考這個帖子  http://www.blogjava.net/xuechen0721/archive/2006/04/29/44040.html

大致就是說,.shutdownOutput()這個方法是關閉輸出流,而不是關閉Socket對象本身,把這個方法放到一個流的末尾,表示我已經給你(客戶端或服務端)傳完信息了,你不需要在等待接收信息了

.shutdownInput()這個方法類似。

不用socket.shutdownOutput()來做每段消息的結束標志時,還可以用下邊的方法

//pw.write("這是"+info+"包裝后的返回結果\r\n");   //注意\r\n是作為結束標志的
pw.println("這是"+info+"包裝后的返回結果");    //prinltn和prinlt,write比較,prinltn自帶換行,也可以當做結束標志

socket.shutdownOutput()雖然沒有關閉該Socket對象但是不能后續用該Socket對象傳輸發送數據了,必須關閉后重新new一個新的Socket。

2.Socket關閉問題

之前寫了個Socket做監聽代理,用Executor起了線程池接收Socket請求,當時服務端的用 socket = serverSocket.accept() 得到的socket在用完后沒有關閉,只在客戶端使用Socket時關閉了,程序部署上去一段時間,發現服務器上這個端口狀態都是CLOSE_WAIT,

一直占滿線程保持CLOSE_WAIT狀態導致后續Socket客戶端沒法再“被接收”。后來在服務端加了一行代碼,使用結束后服務端也關閉Socket對象。之后再測試,就是TIME_WAIT狀態了,過段時間自己就關閉了。

PS:以前一直以為客戶端和服務端Socket用的是一條通信“線”路,就像打電話一樣,A(客戶端)和B(服務端)通話,A主動掛斷了,B肯定也“被動”掛斷了,其實不是這樣的;真實情況是A主動掛斷了,B肯定也會保持打電話的姿態。

3. ServerSocket.setReuseAddress(true) 啟動端口重用,這行代碼一定要放到綁定端口前。

serverSocket =new ServerSocket();
serverSocket.setReuseAddress(true);//這個設置要放在綁定端口前
serverSocket.bind(new InetSocketAddress(serverPort));
pool = Executors.newFixedThreadPool(poolNum);
        
logger.info("啟動監聽端口:"+serverPort);
while(true){
     socket = serverSocket.accept();
     pool.execute(new HandleSocketSer(socket));
}

 4.多線程Socket方案

Threadpool   ---java自帶

Executor  ---java自帶

ForkJoin  ---java8自帶

Actor模型   ---scala庫自帶

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM