咱們在寫輸入輸出流中常常是以循環讀取到-1做爲結束符。html
這個在文件的讀寫中,是沒有問題的,很顯然文件有結束符。
java
這個在socket通信中,是有問題的,socket.getInputStream().read(buffer)這個函數,會處於阻塞狀態,繼續等待對方發數據過來。顯然不可能中斷,即便發一個-1,read也會把-1看成一個值讀出來,循環仍將繼續。socket
網上有一個解決方法:利用socket.setSoTimeout(),在第一次讀取數據後,超過指定的時間,將發生異常,這時候,捕獲異常,使程序繼續進行。函數
我一個同事這樣處理:利用inputStream.available(),來判斷inputStream中是否還有可讀取的值,若是沒有,則跳出循環。測試
這兩種作法都有弊端。google
第一種作法,本生邏輯上就不合正常的思惟,通常來講,咱們是要避免拋異常的,這樣作會使得程序寫起來很彆扭,理解起來也相對困難。另外,咱們通常是經過傳InputStream做爲參數的,如private byte[] getEncodedData(InputStream is),這個時候,就必須傳sokcet做爲參數,不合邏輯。其它的就再也不說了。spa
第二種作法:根據jdk提供的文檔,Note that while some implementations of InputStream will return the total number of bytes in the stream, many will not. 這句話說明,這個available值不可靠。.net
後來,也是網上的朋友有仔細思考過這個問題,我仔細查看socket函數,可利用socket.shutdownOutput(),能夠很好的解決這個問題。此函數能夠,禁用此套接字的輸出流。對於 TCP 套接字,任何之前寫入的數據都將被髮送,而且後跟 TCP 的正常鏈接終止序列。 若是在套接字上調用 shutdownOutput() 後寫入套接字輸出流,則該流將拋出 IOException。debug
後來我仔細想了想。code
這種通用問題,別人應該也碰過,應該有已經解決的方法,不過我在google和baidu上找了好多網頁,才發現這個提示,而這個提示的來源,仍是國外的,呵呵。另外既然是通用問題,寫socket類的人是否已經意識到,並提供解決方案呢,這顯然已經獲得印證。
下面是關鍵代碼,已經測試經過,由於是項目中代碼,無法給全代碼,想實現的同窗,本身補充完善,網上不少,本身寫也不難。
服務端:
/**
* 此方法用於從輸入流中獲取數據
*
* @param is 接收來自客戶端socket對應的輸入流
* @return 返回endodedData
* @throws IOException 拋出的異常,統一在run函數處理
*/
private byte[] getEncodedData(InputStream is) throws IOException {
byte[] maxBuffer = new byte[1024 * 64];
int length = 0;
int lengthTemp = 0;
while (-1 != (lengthTemp = is.read(maxBuffer))) { // read方法並不保證一次能讀取1024*64個字節
length += lengthTemp;
if (length >= 1024 * 64) {
logger.debug("讀入的數據超過1024 * 64");
break;
}
}
byte[] endodedData = new byte[length];
System.arraycopy(maxBuffer, 0, endodedData, 0, length);
logger.info("receiveData:" + DataUtil.bytesToHexString(endodedData) + '\n');
return endodedData;
}
客戶端:
......
os.write(encodedData);
os.flush();
socket.shutdownOutput();
......
參考資料:
java Socket InputStream 阻塞 問題 :http://charseller.iteye.com/blog/941350
java InputStream讀取數據問題 :http://www.cnblogs.com/MyFavorite/archive/2010/10/19/1855758.html
讀取InputStream輸入流的例子 :http://xuzw13.blog.163.com/blog/static/103147165201152010224717/
粗淺理解,還望同窗們指正。
歡迎閱讀相關文章:http://hi.csdn.net/linchengzhi