当前位置: 代码迷 >> J2SE >> 急 socket 客户端接收大于10K的数据,接收不完整,该怎么解决
  详细解决方案

急 socket 客户端接收大于10K的数据,接收不完整,该怎么解决

热度:119   发布时间:2016-04-23 19:46:51.0
急! socket 客户端接收大于10K的数据,接收不完整
我对socket不熟悉,但是这个事挺急,请各位帮我看看。谢谢了啊 ,分不够再加!!!

socket 向服务端请求数据,返回的数据如果小于10K,那么能看到xml的整个完整的格式如下:
<?xml version="1.0" encoding="GBK"?>
<root>
    <header>
          <name>
          ....
          </name>
     .....
</header>
</root>

如果大于10K,XML就不完整了,解析出来少了一部分,反正看不到结尾的</root>节点....  换成循环读取貌似也是一样。。客户端代码如下:




public String buildSocket4Sync(SocketConn sm, HostVO address, String cmd)
{
BufferedReader br = null;
InputStream in = null;
String result = "";
try
{
socket = new Socket(address.getIp(), address.getPort());
OutputStream socketOut = socket.getOutputStream();
socketOut.write(cmd.getBytes());
socketOut.write("\r\n".getBytes());

in = socket.getInputStream();
br = new BufferedReader(new InputStreamReader(in, "utf-8"));
String re;
StringBuffer sbf = new StringBuffer();
while ((re = br.readLine()) != null)
{
sbf.append(re);
}

if (sbf.length() != 0)
{
result = new String(Base64.decode(sbf.toString()), "utf-8");
// System.out.println(result);

}

}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
if (null != br)
{
br.close();
}
in.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
return result;
}



急啊,感谢感谢!
------解决思路----------------------
将缓冲区设置大一点试试。
------解决思路----------------------
要断点调试,看看服务端是否发送完毕,或者接收端没有处理完收到的数据
------解决思路----------------------
socket通讯最好是依据一个协议
就是内容由报文头+报文体
报文头可以用固定的几个字节来表示报文体的长度
读取了报文头的内容后得出报文体的长度
然后再读取那个长度的字节就可以
------解决思路----------------------
像这种大字节的socket通讯,还可以做成分页发送,所以协议很重要
------解决思路----------------------
抓包分析下服务器端返回的数据是否完整。如果是HTTP协议,建议查看返回的 content-length和返回代码206表示只返回了部分。
------解决思路----------------------
你readline的问题,最后可能没有加\r\n所以它一直以为没有最后结束
你可以直接读byte或者加上\r\n
------解决思路----------------------
记得flush一下
------解决思路----------------------
你们的传输的包设计的不好,按行读更是容易出问题:re = br.readLine()

自己设计一个包格式,例如:前4个字节表示消息的大小,然后跟消息的主体,所以包的大小就是 4 + 消息的大小。
接收端检测收到的消息先看前4个字节读出消息的大小,等到有这么多bytes后才读出消息。这种做法懂的不难,不懂得看上去一头雾水。

那么我推荐
1. 用Netty,Mina等成熟的工具来开发。
2. 用消息队列,如RabbitMQ开传消息。

这两种方式比自己写Socket好很多,消息的传达也不会丢失,学习都非常简单,1天的时间就能学会并使用。
------解决思路----------------------
 @Override
    public void messageReceived(IoSession session, Object message) throws Exception
    {
        logger.debug("Receive Server message " + message);
        super.messageReceived(session, message);
        releaseSession(session);
    }
这里是不是不应该 releaseSession(session);呢?
------解决思路----------------------
引用:
使用MINA也需要约定 数据的格式吗? 比如 数据总长度+字节数  ?
对的,nio会有粘包发生的
------解决思路----------------------
你这是本机调的结果,还远程调的结果。
  相关解决方案