java和c使用socket通信时,发送报文的问题 80C

问题详细描述: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;
    }
}

3个回答

除了报文结构,还需要具体的协议文档,比如登录/注销/发送消息,具体需要什么样的数据。

报文收发,最终需要的类型是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[]
m0_38035616
梦说别停留等待 这个我看过,我现在只能改Java客户端,不能修改服务端,服务端是十几年前的,找不到源码了
9 个月之前 回复

你发送的char类型的数据都要转变成byte 类型的数据,包括你的String 类型的数据,
在发送时都需要转变byte[] 数组类型

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐