问题详细描述:java是客户端,c语言是服务端。程序的目的是java发送报文过去 ,服务器能够识别。但是c语言写的服务端是很多年前的,目前已经无法对服务端作任何修改,c接收报文是用char定义的,报文是定长报文,不够的用空格补全,格式为包头+报文长度+报文内容(1字节+4字节+300字节),包头是6,报文长度是0300,报文内容由下图的结构体定义。java使用getBytes()方法,获取了字节数组,发送过去后服务端报错,报错信息为包头错误,后来发现那边接收的是6对应ASCII码,请问这应该如何解决呢?java测试代码如下
package Demo01;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class send {
public static void main(String[] args) {
try {
iSend("172.33.xx.xx",10000);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void iSend(String IP,int PORT) throws IOException{
String baotou = "6";
String blen= "0300";
String id = "0001";
String sysid = "1111";
String sysname = "disk";
String type = "11";
String level = "1";
String content = "sendcontent";
Socket socket = null;
BufferedOutputStream bos = null;
String message = "" ;
List <Object> messList = new ArrayList();
messList.add(baotou);
messList.add(blen);
messList.add(id);
messList.add(sysid);
messList.add(sysname);
messList.add(type);
messList.add(level);
messList.add(content);
List <Object> messList2 = new ArrayList();
messList2.add(changeString(messList.get(0).toString(),1));
messList2.add(changeString(messList.get(1).toString(),4));
messList2.add(changeString(messList.get(2).toString(),4));
messList2.add(changeString(messList.get(3).toString(),8));
messList2.add(changeString(messList.get(4).toString(),16));
messList2.add(changeString(messList.get(5).toString(),16));
messList2.add(changeString(messList.get(6).toString(),16));
messList2.add(changeString(messList.get(7).toString(),240));
for(Iterator<Object> it = messList2.iterator();it.hasNext();){
message += it.next();
}
System.out.println("报文为:"+message);
try {
socket = new Socket(IP,PORT);
bos = new BufferedOutputStream(socket.getOutputStream());
byte [] buf = message.getBytes();
bos.write(buf,0,buf.length);
bos.flush();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(socket != null){
socket.close();
}
}
}
/**
*
*设置定长报文,用空格补齐
* @param object 报文集合
* @param len 报文的规定长度
* @return
*/
public static String changeString(String list,int len){
for(int ListLen = list.length();ListLen < len;ListLen++){
list +=" ";
}
return list;
}
}
https://blog.csdn.net/yutianzuijin/article/details/24807417
除了报文结构,还需要具体的协议文档,比如登录/注销/发送消息,具体需要什么样的数据。
报文收发,最终需要的类型是byte[],
可以直接new byte[],然后对每个字节进行设置,
byte[] packet = new byte[1 + 4 + 300];
packet[0] = ...
packet[1] = ...
...
for(){
packet[...] = ...
}
...
也可以借助某些已有的类,例如用ByteBuffer类
API参考
https://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html
基本流程:
//定义各个参数字符串
String id ...
id字符串填充空格 ....
byte[] idbytes = id.getBytes(); //字符串转byte[]
//其他字符串一样处理
...
ByteBuffer buf = ByteBuffer.allocate(1 + 4 + 300); //创建bytebuffer
buf.putChar(0, '6'); //包头
buf.putInt(1, 300); //报文长度
buf.put(idbytes, 5, idbytes.length); //id
buf.put(sysidbytes, 9, sysidbytes.length); //sysid
...
byte[] packet = buf.array(); //得到最终要发送的byte[]
你发送的char类型的数据都要转变成byte 类型的数据,包括你的String 类型的数据,
在发送时都需要转变byte[] 数组类型