中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java Socket無法完全接收返回內容怎么辦

發布時間:2021-10-27 15:42:18 來源:億速云 閱讀:130 作者:小新 欄目:開發技術

這篇文章給大家分享的是有關java Socket無法完全接收返回內容怎么辦的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

錯誤現象

java Socket無法完全接收返回內容怎么辦

再來看看調試工具結果:

java Socket無法完全接收返回內容怎么辦

讓我們來看看客戶端代碼,調用方法如下:(該方法適用于返回報文前兩個字節表示長度的情況:2字節報文長度 + 內容主體)

public static void test() {
		SocketClient client = new SocketClient();
		// 建立socket對象
		int iret = client.connect("192.168.1.105", 1234);
		if (iret == 0) {
			// 發送數據
			client.write("helloworld".getBytes());
			// 接收數據
			byte data[] = client.read();
			if ((data != null) && (data.length != 0)) {
				// 處理接收結果
				Utils.print("響應報文字節數組---->" + Arrays.toString(data));
			}
		}		
	}

SocketClient.java源碼:

public class SocketClient { 
	// 存儲接收數據
	private byte m_buffer[] = new byte[0x10000];
	private Socket m_socket;
	private InputStream m_inputstream;
	private OutputStream m_outputstream;
	private BufferedInputStream m_bufferedinputstream;
	private BufferedOutputStream m_bufferedoutputstream;
	private boolean connected; 
	public int connect(String host, int port) {
		try {
			SocketAddress socketAddress = new InetSocketAddress(host, port);
			m_socket = new Socket();
			m_socket.connect(socketAddress, 5000);
			m_socket.setSoTimeout(60000);
 
			m_inputstream = m_socket.getInputStream();
			m_bufferedinputstream = new BufferedInputStream(m_inputstream);
			m_outputstream = m_socket.getOutputStream();
			m_bufferedoutputstream = new BufferedOutputStream(m_outputstream);
		} catch (Exception e) {
			return -1;
		}
		connected = true;
		return 0;
	}
 
	/**
	 * 發送請求數據
	 * 
	 * @param data
	 * @param start
	 * @param end
	 * @return
	 */
	public int write(byte data[]) {
		if (data == null || data.length == 0 || !connected) {
			return 0;
		}
		try {
			m_bufferedoutputstream.write(data, 0, data.length);
			m_bufferedoutputstream.flush();
		} catch (Exception e) {
			return -1;
		}
		return 0;
	}
	
	/**
	 * 讀取返回數據
	 * 
	 * @return
	 */
	public byte[] read() {
		if (!connected) {
			return null;
		}
		int len = -1;
		try {
			// 長度不正確,有時返回4,有時返回73
			len = m_bufferedinputstream.read(m_buffer, 0, 0x10000);
		} catch (Exception e) {
			len = 0;
		}
		if (len != -1) {
			return null;
		} else {
			byte ret[] = new byte[len];
			for (int i = 0; i < len; i++) {
				ret[i] = m_buffer[i];
			}
			return ret;
		}
	}
}

通過代碼調試,發現問題出現在inputsream.read方法上,java API對其描述如下:

int java. io. BufferedInputStream.read( byte[] buffer, int offset, int byteCount) throws IOException

Reads at most byteCount bytes from this stream and stores them in byte array buffer starting at offset offset. Returns the number of bytes actually read or -1 if no bytes were read and the end of the stream was encountered. If all the buffered bytes have been used, a mark has not been set and the requested number of bytes is larger than the receiver's buffer size, this implementation bypasses the buffer and simply places the results directly into buffer.

Overrides: read(...) in FilterInputStream
Parameters:
buffer the byte array in which to store the bytes read.
offset the initial position in buffer to store the bytes read from this stream.
byteCount the maximum number of bytes to store in buffer.
Returns:
the number of bytes actually read or -1 if end of stream.
Throws:
IndexOutOfBoundsException - if offset < 0 or byteCount < 0, or if offset + byteCount is greater than the size of buffer.
IOException - if the stream is already closed or another IOException occurs.

引起錯誤原因在于

客戶端在發送數據后,過快地執行read操作,而這時服務端尚未完全返回全部內容,因此只能讀到部分字節。于是換了個思路:

public class SocketClient { 
	private Socket m_socket;
	private InputStream m_inputstream;
	private OutputStream m_outputstream;
	private BufferedInputStream m_bufferedinputstream;
	private BufferedOutputStream m_bufferedoutputstream;
	private boolean connected; 
	public int connect(String host, int port) {
		try {
			SocketAddress socketAddress = new InetSocketAddress(host, port);
			m_socket = new Socket();
			m_socket.connect(socketAddress, 5000);
			m_socket.setSoTimeout(60000);
 
			m_inputstream = m_socket.getInputStream();
			m_bufferedinputstream = new BufferedInputStream(m_inputstream);
			m_outputstream = m_socket.getOutputStream();
			m_bufferedoutputstream = new BufferedOutputStream(m_outputstream);
		} catch (Exception e) {
			return -1;
		}
		connected = true;
		return 0;
	}
 
	/**
	 * 發送請求數據
	 * 
	 * @param data
	 * @param start
	 * @param end
	 * @return
	 */
	public int write(byte data[]) {
		if (data == null || data.length == 0 || !connected) {
			return 0;
		}
		try {
			m_bufferedoutputstream.write(data, 0, data.length);
			m_bufferedoutputstream.flush();
		} catch (Exception e) {
			return -1;
		}
		return 0;
	}
	
	/**
	 * 讀取返回數據
	 * 
	 * @return
	 */
	public byte[] read() {
		if (!connected) {
			return null;
		}
		try {
			return readStream(m_bufferedinputstream);
		} catch (Exception e) {
			return null;
		}
	}
	
	/**
	 * @功能 讀取流
	 * @param inStream
	 * @return 字節數組
	 * @throws Exception
	 */
	public static byte[] readStream(InputStream inStream) throws Exception {
		ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = -1;
		while ((len = inStream.read(buffer)) != -1) {
			outSteam.write(buffer, 0, len);
		}
		outSteam.close();
		inStream.close();
		return outSteam.toByteArray();
	}
	
	public static void test() {
		SocketClient client = new SocketClient();
		// 建立socket對象
		int iret = client.connect("192.168.1.105", 1234);
		if (iret == 0) {
			// 發送數據
			client.write("helloworld".getBytes());
			// 接收數據
			byte data[] = client.read();
			if ((data != null) && (data.length != 0)) {
				// 處理接收結果
				Utils.print("響應報文字節數組---->" + Arrays.toString(data));
			}
		}		
	}
}

測試通過.....

可參考以下解決思路

protected byte[] readMessage(BufferedInputStream is) throws IOException {
		//        MyLog.d(TAG,"=======>readMessage--inputStream=" );
		        int offset = 0;
		        int messageStartOffset = -1;
		        int wait = 0;
		        int messageEndOffset = -1;
		        int findStartOffset = -1;
 
		        while(messageEndOffset==-1||(messageEndOffset+2)>offset){
		            if(is.available()==0){
		                try {
		                    Thread.sleep(MESSAGE_WAIT_INTERVAL);
		                    wait += MESSAGE_WAIT_INTERVAL;
		                } catch (InterruptedException ex) {
		                }
		                if(wait>=MESSAGE_OVERTIME){
		                //超時錯誤
		                    throw new RuntimeException(EXCEPTION_TIMEOUT);
		                }
		                continue;
		            }
		            
		            offset += is.read(messageBuffer, offset, is.available());//讀出數據
		            TestMessage.showBytes(messageBuffer, 0, offset, "MESSAGE");
		            if(messageStartOffset==-1){ //未找到報文頭
		                if(findStartOffset<0)
		                    findStartOffset = 0;
		                messageStartOffset = findStartOffset(messageBuffer, findStartOffset, offset);//查找報文頭
		                MyLog.e(TAG, "messageStartOffset="+messageStartOffset);
		                if(messageStartOffset>=0){//找到報文頭
		                    if(messageStartOffset<2){
		                        //報文錯誤
		                        throw new RuntimeException(EXCEPTION_MSG_PARSE_ERROR);
		                    }else{
		                        int iMessageLength = ((messageBuffer[messageStartOffset-2]&0xff)<<8)+
		                         (messageBuffer[messageStartOffset-1]&0xff);
		//                        MyLog.e(TAG, "iMessageLength="+iMessageLength);
		                        int ignoreInvalidLength = messageStartOffset-4;
		                        messageEndOffset = iMessageLength + ignoreInvalidLength;
		//                        MyLog.e(TAG, "messageStartOffset="+messageStartOffset);
		                        MyLog.e(TAG, "messageEndOffset="+messageEndOffset);

如果想要讓程序保證讀取到count個字節,最好用以下代碼:

int count = 100;  
byte[] b = new byte[count];  
int readCount = 0; // 已經成功讀取的字節的個數  
while (readCount < count) {  
    readCount += inStream.read(b, readCount, count - readCount);  
}

這樣就能保證讀取100個字節,除非中途遇到IO異常或者到了數據流的結尾情況!

感謝各位的閱讀!關于“java Socket無法完全接收返回內容怎么辦”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

泰兴市| 克东县| 威信县| 成安县| 牡丹江市| 庐江县| 肥东县| 梅河口市| 开远市| 张家港市| 隆林| 汕尾市| 台南市| 平顶山市| 古浪县| 洪雅县| 横峰县| 佳木斯市| 南华县| 鄂温| 河北省| 荔浦县| 攀枝花市| 肇庆市| 邯郸县| 扶余县| 南宁市| 兖州市| 杭州市| 博客| 绥江县| 大冶市| 方正县| 枞阳县| 廊坊市| 阳泉市| 昭通市| 达拉特旗| 甘德县| 上栗县| 临高县|