Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What if java Socket cannot fully receive the returned content?

2025-01-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article shares with you what to do if java Socket cannot fully receive the returned content. The editor thinks it is very practical, so share it with you as a reference and follow the editor to have a look.

Error phenomenon

Let's take a look at the debugging tool results:

Let's take a look at the client code, and the calling method is as follows: (this method is suitable for the case where the length of the first two bytes of the returned message is represented by the length of the 2-byte message + the content body)

Public static void test () {SocketClient client = new SocketClient (); / establish socket object int iret = client.connect ("192.168.1.105", 1234); if (iret = = 0) {/ / send data client.write ("helloworld" .getBytes ()) / / receive data byte data [] = client.read () If ((data! = null) & & (data.length! = 0) {/ / process the received result Utils.print ("response report byte array->" + Arrays.toString (data)) }}}

SocketClient.java source code:

Public class SocketClient {/ / Storage received data private byte m_buffer [] = new byte [0x10000]; private Socket masked sockets; private InputStream masks inputstream; private OutputStream masks outputstreams; private BufferedInputStream masks bufferedoutputstreams; private BufferedOutputStream masks bufferedoutputstreams; 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 } / * send request data * * @ 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 } / * read returned data * * @ return * / public byte [] read () {if (! connected) {return null;} int len =-1 Try {/ / length is incorrect, sometimes 4, sometimes 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));}

The test passed.

Please refer to the following solution: 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) {/ / timeout error throw new RuntimeException (EXCEPTION_TIMEOUT) } continue;} offset + = is.read (messageBuffer, offset, is.available ()); / / read data TestMessage.showBytes (messageBuffer, 0, offset, "MESSAGE") If (messageStartOffset==-1) {/ / No header if (findStartOffset=0) {/ / found header if (messageStartOffset)

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report