lyong0703
lyong0703
2009-09-10 11:46

关于Socket中的数据流获取

已采纳

诚心请教,这段时间在做一个项目,一个GPRS的数据中心。GPRS终端通过Internet将数据传输至数据中心。所以我设想通过Socket去实现通讯。在做model的时候却出现了一个问题。我获取的一段心跳数据出现了错误,做数据比对是用十六进制的形式进行比对的(源数据是十六进制)。代码如下,不知道我错在什么地方请各位指点。[code="java"]
private BufferedReader getReader(Socket socket) throws IOException {
InputStream socketIn = socket.getInputStream();
return new BufferedReader(new InputStreamReader(socketIn));
}[/code]
[code="java"]
in= getReader(connection);
String str="";
while((str=in.readLine())!=null){

System.out.println("has receive....");
System.out.println("收到原码:"+str);
System.out.println("转换为16:"+ String2Hex(str));

if(str.equals("end"))

break;

}

connection.close();

}[/code]
转换成16进制的代码如下:
[code="java"]
public static String String2Hex(String s){
String str = "";
for(int i=0;i<s.length();i++){
int ch = s.charAt(i);
String ss = Integer.toHexString(ch);
str = str + ss;
}
return str.toUpperCase();
} [/code]
我自己分析了一下,但是不知道我的分析是否正确。我分析是在获取Socket的流时候就已经出现了错误,也就是
[code="java"]
InputStream socketIn = socket.getInputStream();
return new BufferedReader(new InputStreamReader(socketIn));

[/code] 所以str=in.readLine()就已经是一列错误的字符串了
[code="java"]该心跳包正确的16进制串为:6831003100689B13727077000260000001006A166831003100689B13727077000260000001006A166831003100689B13727077000260000001006A166831003100689B13727077000260000001006A166831003100689B13727077000260000001006A166831003100689B13727077000260000001006A16
我解析的为:68310310689b13727077026000106a1668310310689b13727077026000106a1668310310689b13727077026000106a1668310310689b13727077026000106a1668310310689b13727077026000106a1668310310689b13727077026000106a16
[/code]

[b]问题补充:[/b]
感谢megcker 但是问题还是没有解决啊 期待
[b]问题补充:[/b]
6831031068fffd727077026000106a16
这是我使用megcker提供的方法解析出来的前部分
[b]问题补充:[/b]
tfqjavaeye 说的这个控制字符没有读取出来的信息是一种思考的方向。但却不是做了((str=in.readLine())!=null)这个判断的原因。当我不用这个判断直接读取以后就转换也还是一样的缺少0
[b]问题补充:[/b]
以上解释出来的用的是[code="java"]DataInputStream dis = new DataInputStream(connection.getInputStream());

//BufferedReader streamReader = getReader(connection);

System.out.println("服务器接收到客户端的连接请求:" + String2Hex(dis.readLine())); [/code]
解析出来的为::68310310689b13727077026000106a1668310310689b13727077026000106a1668310310689b13727077026000106a1668310310689b13727077026000106a1668310310689b13727077026000106a1668310310689b13727077026000106a16

我在[url]http://www.leftworld.net/online/j2sedoc/javaref/java.io.datainputstream_dsc.htm#readUTF(java.io.DataInput)[/url]这里发现一段话
数据输入流和数据输出流以稍加修订的 UTF-8 格式表示 Unicode 字符串。
。。。。。。
这种格式与“标准的”UTF-8 格式的区别如下:
Null 字符 '\u0000' 用两个字节而不是一个字节格式编码,所以编码后的字符串永不会包含空字符。
不是到是不是因为他编码后的字符串不包含空字符才会导致 我在解析出来的数据中缺少0 也就是tfqjavaeye说的
[b]问题补充:[/b]
问题已经解决了 dwangel 的说法很正确啊 一直都只盯着流 却忽略了这里 多谢各位了

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

6条回答

  • iteye_7589 iteye_7589 12年前

    原来以为你是传的字符……

    如果二进制字串,不要用 reader,reader是面向char
    会按char编码.
    两个字节的 0 0 会被合并成一个0 .......

    直接用InputStream读byte数组

    点赞 评论 复制链接分享
  • iteye_158 iteye_158 12年前

    首先 不同操作系统 不同服务器 对高低位的设置是不一样的 比如你向AIX下 发生字节 就会出错 所以我个人建议你用字符,,,,,,

    点赞 评论 复制链接分享
  • weixin_42302405 weixin_42302405 12年前

    你的解析与正确的结果的差异在于0的个数不对,其余不是0的字符都能对上。顺便问下,你的解析结果中的小写字母应该是大写的吧。
    ASCii码中十进制的值为0的字符是null,也就是空。但是后面的解释说是“控制字符”,我认为是输入流中的一些控制字符你没有读进来,导致你转换后0的个数减少。因为你做了str=in.readLine())!=null的判断。也不知道到发送端是怎样将原始数据转换为字符串的,所以不能确定。希望对你有所帮助。

    点赞 评论 复制链接分享
  • iteye_7589 iteye_7589 12年前

    用stream处理网络数据经常注意,有时候,数据是分多次传来的。(刚好分多个数据包了)

    如果不知道完整的长度的话,
    等待一段时间,直到超时比较好。

    点赞 评论 复制链接分享
  • megcker megcker 12年前

    你可以用这样的方式获得相关报文:
    [code="java"]DataInputStream serverIn;//输入报文
    serverIn = new DataInputStream (
    new BufferedInputStream (socket.getInputStream ())
    );
    byte[] b=new byte[1024];
    serverIn.read (b)[/code]

    点赞 评论 复制链接分享
  • megcker megcker 12年前

    socket获得的是什么码?如果是hex码很多是不可见字符!

    点赞 评论 复制链接分享

相关推荐