论坛首页 Java企业应用论坛

Java socket编程客户端读取数据不完整

浏览 7351 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2013-10-29  
今天在用java socket读取服务器端发送的数据时,发现只能读取服务器端发送的部分数据,无法完整读取服务器端的数据。数据大概有7W多个字节。

原代码如下:
    private String getSocketDCCReceiveCCA() throws IOException{
InputStream stream=socket.getInputStream();
byte[] rb = new byte[8];
socket.getInputStream().read(rb);
                  //前8个字节是整个xml数据的长度(十六进制)
int rLen =b2i(rb);
Log.info("转换后的rLen长度为:"+rLen);
byte[] read = new byte[rLen - 8];
                  //一次性读取数据的长度(这里有7W多个字节)
socket.getInputStream().read(read);
                  //对数据进行编码转换
String re = new String(CheckUnicodeString(read), "UTF-8");
                  return re;
         }


请各位帮忙看看,为什么服务器端返回的字符串有7W多个,而我这边只接收到几千个字节。
   发表时间:2013-10-31  
这很正常啊,读不完接着读,直到读完或超时为止
1 请登录后投票
   发表时间:2013-11-01  
可以传过来长度
0 请登录后投票
   发表时间:2013-11-01  
xlaohe1 写道
可以传过来长度


正解。内容前面放文件大小,有多少,就读多少
0 请登录后投票
   发表时间:2013-11-01  
你们真逗,楼主不是说了 //前8个字节是整个xml数据的长度(十六进制) 了吗。。。
所以他是拿到了长度,但是没有读取到那么多字节。

楼主,你的代码有两个问题:
1 是功能上的,inputstream的read(byte[])方法不是一个void方法,没有任何文档说他可以保证填充满byte[]。 在读取中出现异常/超时的时候,是等待/抛出异常/还是仅返回已经填充的长度,是由inputstream的具体实现去决定的。 你可以拿到read方法的返回值,检查是否读完整了,是否需要继续 read(byte[], offset, length)

2 是性能上的。。。你把几万字节写到byte array和string里面也太坑爹了吧。。。如果你的XML API可以直接用InputStream,为什么不直接用stream呢。就算要先存下来,也应该存个临时文件什么的吧。
1 请登录后投票
   发表时间:2013-11-09  
public final int read(byte[] b) throws IOException
从包含的输入流中读取一定数量的字节,并将它们存储到缓冲区数组 b 中。以整数形式返回实际读取的字节数。在输入数据可用、检测到文件末尾 (end of file) 或抛出异常之前,此方法将一直阻塞。

// 读取实际的对象内容 
                buffer = new byte[objContentleng]; 
                int nIdx = 0; 
                int nTotalLen = buffer.length; 
                int nReadLen = 0; 
                
                while (nIdx < nTotalLen) 
                { 
                    nReadLen = bis.read(buffer, nIdx, nTotalLen - nIdx); 
                    
                    if (nReadLen > 0) 
                    { 
                        nIdx = nIdx + nReadLen; 
                    } 
                    else 
                    { 
                        break; 
                    } 
                }
1 请登录后投票
   发表时间:2013-11-13  
我前几天也遇到同样的问题。结果找出原因,必须使用原始的InputStream,使用Reader就会有问题的。
1 请登录后投票
   发表时间:2013-11-22  
谢谢各位的帮助!下面是我写的一个方法。请赐教!

private String getSocketDCCReceiveCCA() throws IOException{
InputStream stream=socket.getInputStream();
byte[] rb = new byte[8];
socket.getInputStream().read(rb);
Log.info("rb1==="+new String(rb));
int rLen =b2i(rb);
Log.info("after change rLen.length=:"+rLen);

StringBuffer stringBuffer=new StringBuffer();
byte[] c; 
int i=0; //每次实际读取的字节数
int count=0; //已经读取的字节数
c=new byte[rLen-count];
i=socket.getInputStream().read(c);
count=count+i;
//总的字节数减去已经读取的字节数就是下次要读取的字节数
stringBuffer.append(new String(c,0,i,"UTF-8").trim());
while(count!=(rLen-8)){
//继续读取字节
c=new byte[rLen-count];
i=socket.getInputStream().read(c);
count=count+i;
stringBuffer.append(new String(c,0,i,"UTF-8").trim());
}

Log.info("新的方式得到的字符串为:"+stringBuffer.toString());
//return new String(CheckUnicodeString(stringBuffer.toString().getBytes()),"UTF-8");
return stringBuffer.toString();

}
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics