广告
返回顶部
首页 > 资讯 > 精选 >java Socket无法完全接收返回内容怎么办
  • 133
分享到

java Socket无法完全接收返回内容怎么办

2023-06-25 11:06:52 133人浏览 八月长安
摘要

这篇文章给大家分享的是有关java Socket无法完全接收返回内容怎么办的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。错误现象再来看看调试工具结果:让我们来看看客户端代码,调用方法如下:(该方法适用于返回报文前

这篇文章给大家分享的是有关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;} 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;}public byte[] read() {if (!connected) {return null;}int len = -1;try {// 长度不正确,有时返回4,有时返回73len = 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;} 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;}public byte[] read() {if (!connected) {return null;}try {return readStream(m_bufferedinputstream);} catch (Exception e) {return null;}}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无法完全接收返回内容怎么办”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

--结束END--

本文标题: java Socket无法完全接收返回内容怎么办

本文链接: https://www.lsjlt.com/news/304122.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • java Socket无法完全接收返回内容怎么办
    这篇文章给大家分享的是有关java Socket无法完全接收返回内容怎么办的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。错误现象再来看看调试工具结果:让我们来看看客户端代码,调用方法如下:(该方法适用于返回报文前...
    99+
    2023-06-25
  • java Socket无法完全接收返回内容的解决方案
    目录错误现象引起错误原因在于可参考以下解决思路最近在使用Socket通讯时,遇到了接收内容不全(返回内容 = 4字节报文长度 + 内容主体)的问题:客户端发送请求数据,服务器明明返回...
    99+
    2022-11-12
  • java怎么接收response返回内容
    在Java中可以使用HttpURLConnection或者HttpClient来接收response返回内容。使用HttpURLCo...
    99+
    2023-08-30
    response java
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作