背景:客户端通过TCP连接从服务器接收字串,要把收到的字符串根据指定的分割标志(H#H)分开,然后一条一条进行处理。
服务器每次发过来的消息的长度不会少于150,最长不确定。
用于接收消息的bData长度是4K,目前一次最多收到的消息没有大于3K长度的。
代码如下:
try{
int iLen = 0;
int iPos1 = 0;
int iPos2 = 0;
String sTmp = null;
while(true && chkFlg){
iLen = IS.read(bData);
if ( iLen > 0) {
sTmp = new String( bData);
sTmp = sTmp.trim();
strBuf.append(sTmp);
iPos1 = strBuf.indexOf("H#H");
iPos2 = strBuf.indexOf("H#H",iPos1+100);
while( iPos1>-1 && iPos2>iPos1 ){
sTmp = strBuf.substring(iPos1,iPos2);
strBuf.delete(iPos1, iPos2);
//把消息放到任务线程中去处理
dealMsg(sTmp);
iPos1 = strBuf.indexOf("H#H");
iPos2 = strBuf.indexOf("H#H",iPos1+100);
}
//用“\0”清理掉用于接收消息的bData中的内容
System.arraycopy(bDump,0,bData,0,iBufSize);
}
if ( iLen==-1 ) {
break;
}
}
}
catch(IOException e){
}
代码处理逻辑:服务器每次发过来的append在StringBuffer最后,看到第二个分割符号时,把前边的一条地取出来处理。
环境:服务器在Linux上,客户端所在机器的操作系统不定。
问题:当客户端在Windows上跑或者和服务器放在同一台Linux上时,不论分割符间的串有多短或者多长都正常;
但客户端放到另外一台Linux上就不行了,发过来的全是短些的串没有问题,长的串(比如大于2000的)就会出错,但又不是每次都错,有时候错得多,有时候对的多:
出错情况1、有长串时,一次没有发完,下次才会发完,发现前一次没有处理留在StringBuffer中的串整个儿没有了,里边的内容全成了第二次发过来的了:
第一次过来的:H#H111111H#H2222222(近1500字符),不知道第二个串有没有结束所以只从StringBuffer中处理并delete掉第一条完整的内容,这个时候看StringBuffer里的内容,是H#H2222222....,是正确的没有处理的未完的内容。
第二次收到的:222222222222222222222222222222(也有1000多字符)
这个时候看StringBuffer里的内容,全是第二次的内容了,前边保留的全没有了。
出错情况2、有长串时,三次才能收完,发现第二次发过来的串整个儿没有了:
第一次过来的:H#H111111H#H2222222(近1500字符),不知道第二个串有没有结束所以只从StringBuffer中处理并delete掉第一条完整的内容,这个时候看StringBuffer里的内容,是H#H2222222....,是正确的没有处理的未完的内容。
第二次收到的:222222222222222222222222222222(也有1000多字符)
第三次收到的:333333333333H#Haaaaaaaaaaaaaaa
这个时候看StringBuffer里的内容,第二次的内容没有了,最终第二条消息的内容成了:#H2222222...(这里应该有第二次收到的,却没有)333333333333。请帮忙看看问题在哪儿?不胜感激!!
服务器每次发过来的消息的长度不会少于150,最长不确定。
用于接收消息的bData长度是4K,目前一次最多收到的消息没有大于3K长度的。
代码如下:
try{
int iLen = 0;
int iPos1 = 0;
int iPos2 = 0;
String sTmp = null;
while(true && chkFlg){
iLen = IS.read(bData);
if ( iLen > 0) {
sTmp = new String( bData);
sTmp = sTmp.trim();
strBuf.append(sTmp);
iPos1 = strBuf.indexOf("H#H");
iPos2 = strBuf.indexOf("H#H",iPos1+100);
while( iPos1>-1 && iPos2>iPos1 ){
sTmp = strBuf.substring(iPos1,iPos2);
strBuf.delete(iPos1, iPos2);
//把消息放到任务线程中去处理
dealMsg(sTmp);
iPos1 = strBuf.indexOf("H#H");
iPos2 = strBuf.indexOf("H#H",iPos1+100);
}
//用“\0”清理掉用于接收消息的bData中的内容
System.arraycopy(bDump,0,bData,0,iBufSize);
}
if ( iLen==-1 ) {
break;
}
}
}
catch(IOException e){
}
代码处理逻辑:服务器每次发过来的append在StringBuffer最后,看到第二个分割符号时,把前边的一条地取出来处理。
环境:服务器在Linux上,客户端所在机器的操作系统不定。
问题:当客户端在Windows上跑或者和服务器放在同一台Linux上时,不论分割符间的串有多短或者多长都正常;
但客户端放到另外一台Linux上就不行了,发过来的全是短些的串没有问题,长的串(比如大于2000的)就会出错,但又不是每次都错,有时候错得多,有时候对的多:
出错情况1、有长串时,一次没有发完,下次才会发完,发现前一次没有处理留在StringBuffer中的串整个儿没有了,里边的内容全成了第二次发过来的了:
第一次过来的:H#H111111H#H2222222(近1500字符),不知道第二个串有没有结束所以只从StringBuffer中处理并delete掉第一条完整的内容,这个时候看StringBuffer里的内容,是H#H2222222....,是正确的没有处理的未完的内容。
第二次收到的:222222222222222222222222222222(也有1000多字符)
这个时候看StringBuffer里的内容,全是第二次的内容了,前边保留的全没有了。
出错情况2、有长串时,三次才能收完,发现第二次发过来的串整个儿没有了:
第一次过来的:H#H111111H#H2222222(近1500字符),不知道第二个串有没有结束所以只从StringBuffer中处理并delete掉第一条完整的内容,这个时候看StringBuffer里的内容,是H#H2222222....,是正确的没有处理的未完的内容。
第二次收到的:222222222222222222222222222222(也有1000多字符)
第三次收到的:333333333333H#Haaaaaaaaaaaaaaa
这个时候看StringBuffer里的内容,第二次的内容没有了,最终第二条消息的内容成了:#H2222222...(这里应该有第二次收到的,却没有)333333333333。请帮忙看看问题在哪儿?不胜感激!!
解决方案 »
- java中连接oracle时DATE数据更新问题
- 关于JMenu创建两级菜单问题
- 关于JAVA正则表达式的一个疑惑:怎样匹配乘号*?
- ftp建文件夹后上传发生问题,100分跪求,不够再加,谢谢大家
- 各位老大,小弟问一下,在java中写的单机版程序如何像金山词霸一样,每一个系统,同时只能有一个程序在跑??
- 最容易回答的问题----轻松得分.快来回答??谢谢
- 谁有idea麻烦给我一下
- 大神戳进来,,我的jar包不能运行怎么整?
- 问题:用oci8连oracle,报java.lang.UnsatisfiedLinkError:do_open错误。
- 大伙不觉得jcombobox灰灰的背景色很难看吗,怎么改变?
- 下载网页到指定文件夹。。。。怎样实现啊。。。。?
- 怎么让线程不抢占资源呀。。。谢谢
对于资源strBuf的操作应该是异步的才对,但是从你提供的程序来看没有看到这一点
也就是说当客户端A请求过来,正在处理时,可能此时客户端B也在请求strBuf资源,并对其进行操作.
在你的程序中strBuf是很关键的资源,必须采用很好的机制保证它的线程安全性
在从socket中读到数据后,append上去,然后检查整个buffer,有完整的一段时,就把这一段取出来:
sTmp = strBuf.substring(iPos1,iPos2);
然后再从buffer中删除掉这一段:strBuf.delete(iPos1, iPos2);
再把sTmp中完整的一段内容送到专门的处理线程中处理
之后再到Socket去取数据
这样应该不会再有别的地方来操作strBuf啊
sTmp = sTmp.trim();
你用到了String是不是bData太长导致String溢出了。