十万火急!高手指点#####指点!!!!socket通信如何接收ascii码?在线等待,帮帮忙好吧?周末前一定结帖!

时间:2021-07-03 18:57:58
先要写一SOCKET通信接收信息代码,里面既有二进制码,又有ascii码,我该怎么读取信息啊?JAVA里面IO都是用字符处理的,怎么把ASCII码正确接收然后转化为字符啊?
谢谢!十万火急!你们一点要帮我啊!

23 个解决方案

#1


谁说“JAVA里面IO都是用字符处理”?
字节流和字符流都有啊,用字节流来处理不就行了。

#2


非常感谢!能帮我写一段接收的代码吗?我是想先一整个的接收,再从这一整串中提取不同的内容
我是这样写的:
public void run(){
try{
BufferedReader in=new BufferedReader(new InputStreamReader(socket1.getInputStream()));
PrintWriter out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket1.getOutputStream())),true);    
    address=socket1.getInetAddress().getHostAddress();
    String str;
 Processor Pro = new Processor();
char c[]=new char[500];
int num=in.read(c);
 str=new String(c,0,num);
      String reply=Pro.queryUpgrade(str,address);
    System.out.println(reply);
      out.println(reply);
}
catch(IOException e){
System.err.println("IO Exception");
}
finally{
try{
socket1.close();
}
catch(IOException e){
System.err.println("Socket not closed");
}
}
}
对吗?该怎么改啊!谢谢!

#3


楼上的大哥再说详细一点好吧?确实很急,一定要帮我啊!

#4


你都用BufferedReader了还要问什么
服务器那段不管是用字节流还是字符流,你都可以转换成字符了

#5


关键是我介绍到的都是乱码!!我做的服务器端,
JAVA中一个字符占两个字节。而客户端那端是用C,一个字符就占一个字节,用ASCII码传输,我直接接收,然后提取信息,就是乱码!我改怎么做啊?楼上的两位大哥说明白清楚一点好吗?能不能给一个简单的例子?小妹确实很急,今天晚上就要联合调试了,昨晚加班到十二点,今天还没改好!

#6


怎么用字节流接收,然后从中提取信息啊!
传输的格式采用T(tag)L(length)V(value)格式,T和L都是一个字节的CHAR,(那边是用C写的),我这边怎么样顺利接收T和L啊!谢谢!各位大哥一定要帮帮我啊!

#7


我现在能用字节流接收,然后从字节数组里一个一个读出来。但我现在又有新问题,我该怎么把信息以接收的格式发回去啊?给位仁兄帮忙啊!

#8


为什么不先接受2个字节的T L,然后算出L,再接收L长度的value/
socket接收过来的是byte,只要你确定是ASCII,再把他转成string在java下就能正确显示了.因为java的char虽然是两字节的长度,但是当把c里面的一个字节的char(相当于java里的byte)转过来时,只是在高位补0.你所以看到的是乱码,是不是因为value是二进制,转成string后当然是乱码,但是其实T L都已经正确了,而你没有注意.

#9


用getbytes()把String转成byte数组,因为网络上通用的是字节流.而且L必须是转化后的字节流的长度.

#10


楼上的大哥说得很详细,分析得也很正确,非常感谢!
刚开始我就是采用上面的程序接收的,然后只有VALUE是清晰的,其他的都是乱码。
我用字节流直接读取然后保存在字节数组里,一个一个打印出来后,T和L是普通的INT数字,(因为约定T也用数字代表)但VALUE就都是ASCII吗,我就按照先读T和L,再通过建立STRING 的方式读VALUE,这一次,输出就不是乱码了!应该说读基本上就没问题了。
现在有一个问题就是我不知道我该采用什么方案,发送回复信息,格式也是TLV。再帮我指点指点好吗?

我知道做研发的都很忙,但我还是恳请你们挤出一点时间帮我考虑考虑好吗?谢谢!

#11


TO zengyh(zeng):能不能在发之前再转化为字节数组呢?因为我发的东西有很多项,MAC,FILENAME等等,很多项,不会是一个一个地转化为字节数组,在把这些数组组合成一个再发出去吧?那代码量好大啊!

#12


只要你确定都是ASCII码,应该都可以转.
看你说的,好象你的T和L都是int的编码方式,只是占有一个字节.
我想你可以先生成一个大的buf[500],假如T是100,L是200,你可以直接
buf[0]=(byte)100;buf[1]=(byte)200;
剩下的就是VALUE,你可以用str.getbytes()直接存放到buf的2....n里面去.
我对JAVA的语法不很了解,你可以看看帮助.

#13


谢谢zengyh(zeng),非常感谢!
对,T和L都是int的编码方式,就是占有一个字节。
我试试看。

#14


再问一下:
现在我把T和L都定义为INT型的,V定义成STRING 型。
那我在转化为字节数组之前需不需要先把V转化为ASCII呢?是直接放到字节数组里面吗?

#15


当然不能直接放,因为String里面每个字符以unicode形式存放,占两个字节,而byte只有1个字节.

应该用V.getbytes();得到字节流,再放进去,然后就可以out出去.

#16


嗯,谢谢!我想问这个V要不要转化为ASCII码,因为我们规定V的值是采用ASCII STRING类型。

#17


谢谢楼上大哥的指点,小妹受益匪浅。
我忘了说了,上面那个程序是按照字符接收的,我已经改成按照字节流的方式接收了,代码如下:

public void run(){
try{
InputStream in=new BufferedInputStream(socket1.getInputStream());
OutputStream out=new BufferedOutputStream(socket1.getOutputStream());
 String address=socket1.getInetAddress().getHostAddress();
while(true){
int n=in.available();
byte[]b=new byte[n];
if(n>0){

int result=in.read(b);
if(result==-1)
{break;
}
                 
   Processor Pro = new Processor();
  String reply=Pro.queryUpgrade(b,address);
byte[] a= reply.getBytes();
System.out.println(reply);
out.write(a);
}
in.close();
out.close();
}}

catch(IOException e){
System.err.println("IO Exception");
}
finally{
try{
socket1.close();
}
catch(IOException e){
System.err.println("Socket not closed");
}
}
}
我能顺利接收信息,但对方收到我回的信息却是乱码,我自己打印出来的不是乱码。

#18


我觉得应该是我这一句有问题:String reply=Pro.queryUpgrade(b,address);
这个REPLY格式应该转变一下。

#19


明白了.
如果你接收到的b里面T L确定只有1个字节也就是b[0]和b[1],那就很好办了.说明你的数据包长度绝对不会超过128.

我想你把replay打印出来,看replay有没有含T和L.如果有而且是INT格式的,那象你那样做就可以了.如果replay没有包含T和L,那你就把replay里面的Value取出来放到a[2]...a[n-1]中应该就可以了,然后在a[0]和a[1]里面填上T L.

至于你说要不要转成ASCII码,其实用getBytes()函数就是转成ASCII码了.ASCII其实就是1个字节的byte,用了getBytes()函数就是把char的高8位去掉,把低8位取出来放到了byte[]中.

#20


对,你理解正确,包长是不超过100,
现在关键是我的REPLY里面有很多项,MAC\FILENAME\TFTPADDRESS\UPDATE_SCOPE等,而且还有一些错误信息,也是以TLV格式,每一项都采用TLV格式。我试着按照你说的转化的方法去写一个函数分别把没一项转化为一个数组,然后再合并成一个字节数组,再发送,工作量好大啊!
好心的大哥,再帮我想想好吧!都快晕到了!

#21


不明白搂主你口口声声说客户端是c写的,可是又拿出来java的代码让我们看是什么意思

#22


我是做服务器端,我是先收信息,再发信息

#23


哈哈!终于解决了,用字节流接收信息,用字符流发送信息!非常感谢zengyh(zeng) 的帮助。结贴!

#1


谁说“JAVA里面IO都是用字符处理”?
字节流和字符流都有啊,用字节流来处理不就行了。

#2


非常感谢!能帮我写一段接收的代码吗?我是想先一整个的接收,再从这一整串中提取不同的内容
我是这样写的:
public void run(){
try{
BufferedReader in=new BufferedReader(new InputStreamReader(socket1.getInputStream()));
PrintWriter out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket1.getOutputStream())),true);    
    address=socket1.getInetAddress().getHostAddress();
    String str;
 Processor Pro = new Processor();
char c[]=new char[500];
int num=in.read(c);
 str=new String(c,0,num);
      String reply=Pro.queryUpgrade(str,address);
    System.out.println(reply);
      out.println(reply);
}
catch(IOException e){
System.err.println("IO Exception");
}
finally{
try{
socket1.close();
}
catch(IOException e){
System.err.println("Socket not closed");
}
}
}
对吗?该怎么改啊!谢谢!

#3


楼上的大哥再说详细一点好吧?确实很急,一定要帮我啊!

#4


你都用BufferedReader了还要问什么
服务器那段不管是用字节流还是字符流,你都可以转换成字符了

#5


关键是我介绍到的都是乱码!!我做的服务器端,
JAVA中一个字符占两个字节。而客户端那端是用C,一个字符就占一个字节,用ASCII码传输,我直接接收,然后提取信息,就是乱码!我改怎么做啊?楼上的两位大哥说明白清楚一点好吗?能不能给一个简单的例子?小妹确实很急,今天晚上就要联合调试了,昨晚加班到十二点,今天还没改好!

#6


怎么用字节流接收,然后从中提取信息啊!
传输的格式采用T(tag)L(length)V(value)格式,T和L都是一个字节的CHAR,(那边是用C写的),我这边怎么样顺利接收T和L啊!谢谢!各位大哥一定要帮帮我啊!

#7


我现在能用字节流接收,然后从字节数组里一个一个读出来。但我现在又有新问题,我该怎么把信息以接收的格式发回去啊?给位仁兄帮忙啊!

#8


为什么不先接受2个字节的T L,然后算出L,再接收L长度的value/
socket接收过来的是byte,只要你确定是ASCII,再把他转成string在java下就能正确显示了.因为java的char虽然是两字节的长度,但是当把c里面的一个字节的char(相当于java里的byte)转过来时,只是在高位补0.你所以看到的是乱码,是不是因为value是二进制,转成string后当然是乱码,但是其实T L都已经正确了,而你没有注意.

#9


用getbytes()把String转成byte数组,因为网络上通用的是字节流.而且L必须是转化后的字节流的长度.

#10


楼上的大哥说得很详细,分析得也很正确,非常感谢!
刚开始我就是采用上面的程序接收的,然后只有VALUE是清晰的,其他的都是乱码。
我用字节流直接读取然后保存在字节数组里,一个一个打印出来后,T和L是普通的INT数字,(因为约定T也用数字代表)但VALUE就都是ASCII吗,我就按照先读T和L,再通过建立STRING 的方式读VALUE,这一次,输出就不是乱码了!应该说读基本上就没问题了。
现在有一个问题就是我不知道我该采用什么方案,发送回复信息,格式也是TLV。再帮我指点指点好吗?

我知道做研发的都很忙,但我还是恳请你们挤出一点时间帮我考虑考虑好吗?谢谢!

#11


TO zengyh(zeng):能不能在发之前再转化为字节数组呢?因为我发的东西有很多项,MAC,FILENAME等等,很多项,不会是一个一个地转化为字节数组,在把这些数组组合成一个再发出去吧?那代码量好大啊!

#12


只要你确定都是ASCII码,应该都可以转.
看你说的,好象你的T和L都是int的编码方式,只是占有一个字节.
我想你可以先生成一个大的buf[500],假如T是100,L是200,你可以直接
buf[0]=(byte)100;buf[1]=(byte)200;
剩下的就是VALUE,你可以用str.getbytes()直接存放到buf的2....n里面去.
我对JAVA的语法不很了解,你可以看看帮助.

#13


谢谢zengyh(zeng),非常感谢!
对,T和L都是int的编码方式,就是占有一个字节。
我试试看。

#14


再问一下:
现在我把T和L都定义为INT型的,V定义成STRING 型。
那我在转化为字节数组之前需不需要先把V转化为ASCII呢?是直接放到字节数组里面吗?

#15


当然不能直接放,因为String里面每个字符以unicode形式存放,占两个字节,而byte只有1个字节.

应该用V.getbytes();得到字节流,再放进去,然后就可以out出去.

#16


嗯,谢谢!我想问这个V要不要转化为ASCII码,因为我们规定V的值是采用ASCII STRING类型。

#17


谢谢楼上大哥的指点,小妹受益匪浅。
我忘了说了,上面那个程序是按照字符接收的,我已经改成按照字节流的方式接收了,代码如下:

public void run(){
try{
InputStream in=new BufferedInputStream(socket1.getInputStream());
OutputStream out=new BufferedOutputStream(socket1.getOutputStream());
 String address=socket1.getInetAddress().getHostAddress();
while(true){
int n=in.available();
byte[]b=new byte[n];
if(n>0){

int result=in.read(b);
if(result==-1)
{break;
}
                 
   Processor Pro = new Processor();
  String reply=Pro.queryUpgrade(b,address);
byte[] a= reply.getBytes();
System.out.println(reply);
out.write(a);
}
in.close();
out.close();
}}

catch(IOException e){
System.err.println("IO Exception");
}
finally{
try{
socket1.close();
}
catch(IOException e){
System.err.println("Socket not closed");
}
}
}
我能顺利接收信息,但对方收到我回的信息却是乱码,我自己打印出来的不是乱码。

#18


我觉得应该是我这一句有问题:String reply=Pro.queryUpgrade(b,address);
这个REPLY格式应该转变一下。

#19


明白了.
如果你接收到的b里面T L确定只有1个字节也就是b[0]和b[1],那就很好办了.说明你的数据包长度绝对不会超过128.

我想你把replay打印出来,看replay有没有含T和L.如果有而且是INT格式的,那象你那样做就可以了.如果replay没有包含T和L,那你就把replay里面的Value取出来放到a[2]...a[n-1]中应该就可以了,然后在a[0]和a[1]里面填上T L.

至于你说要不要转成ASCII码,其实用getBytes()函数就是转成ASCII码了.ASCII其实就是1个字节的byte,用了getBytes()函数就是把char的高8位去掉,把低8位取出来放到了byte[]中.

#20


对,你理解正确,包长是不超过100,
现在关键是我的REPLY里面有很多项,MAC\FILENAME\TFTPADDRESS\UPDATE_SCOPE等,而且还有一些错误信息,也是以TLV格式,每一项都采用TLV格式。我试着按照你说的转化的方法去写一个函数分别把没一项转化为一个数组,然后再合并成一个字节数组,再发送,工作量好大啊!
好心的大哥,再帮我想想好吧!都快晕到了!

#21


不明白搂主你口口声声说客户端是c写的,可是又拿出来java的代码让我们看是什么意思

#22


我是做服务器端,我是先收信息,再发信息

#23


哈哈!终于解决了,用字节流接收信息,用字符流发送信息!非常感谢zengyh(zeng) 的帮助。结贴!