Socket 网络通信并解析文件.

本文介绍了一种自定义协议下的Java与C语言通过Socket进行数据传输的方法。具体包括协议结构设计、客户端发送数据和服务器端解析数据的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

          通常在做系统集成应用的时候,Java语言会和C语言就数据的传输和共享达成一致的协议,服务于相应的应用。Java 和C 语言通信的常用方式,主要有两种:JNI 和socket 字节传输。述说JNI的网上有很多的一堆,现在我就简单说说如何在一种自定义的协议下,完成系统见的通信。


以我本机为例,展示socket字节传输,并解析。先看协议,再直接上代码查看:

验证码

Char[8]

8

“PEOPLE10 ”

数据总长

int

4

后续所有数据的长度

协议类型

short

2

协议类型,类型含义如下:

 3、数据集成系统

保留字段

Char[16]

当前版本暂时保留

命令类型

short

2

命令类型,详细如下

8增加关系类型

rel num

Int

4

要操作的关系类型个数

rel len

Int

4

关系类型名称长度

rel name

Char*

Type len

关系名称

Rel weight

Int

4

关系权重

Is_multi

char

1

是否多值,0为单值,1为多值

……

……

……

……

扩展长度

int

4

扩展长度,为以后扩展使用,固定为0

扩展字段

Char*

扩展长度

不需要填写此值


先看客户端干货:

/**
     * 发送数据.
     */
    public static void sendMsg() {
        Socket socket = null;
        OutputStream outs = null;
        try {
            socket = new Socket("127.0.0.1", TestServer.PORT);
            outs = socket.getOutputStream();
            short type = 3;
            byte[] datas = assemblyRelationshipProtocol(type);

            outs.write(datas,0,datas.length);
            outs.flush();
            
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                outs.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public static byte[] assemblyRelationshipProtocol(int type) {
        try {
            List<byte[]> protoList = new ArrayList<byte[]>();
            int dataLen = 0;
           
            int relNum = 1;
            byte[] numByte = DataConvert.intToByteArray(relNum);
            dataLen += 4;
           
            String relName = "朋友";
            byte[] nameByte = relName.getBytes();
            int relNameLen = nameByte.length;

            byte[] lenByte = DataConvert.intToByteArray(relNameLen);
            dataLen += 4;

            dataLen += relNameLen;
    
            

            int right  = 1;
            byte[] rightByte = DataConvert.intToByteArray(right);
            dataLen += 4;

            String IsMult = "1";
            byte[] Is_multiByte = IsMult.getBytes();
            dataLen += 1;

            
            byte[] headProtoByte = null;
            short add=8,del=9;
            if (type == 1) {
                headProtoByte = assemblyHeadProtocol(add, dataLen);
            } else {
                headProtoByte = assemblyHeadProtocol(del, dataLen);
            }
            
            protoList.add(headProtoByte);           
            protoList.add(numByte);
            protoList.add(lenByte);
            protoList.add(nameByte);
                
            protoList.add(rightByte);
            protoList.add(Is_multiByte);
           
            return DataConvert.sysCopy(protoList);
        
        } catch (Exception e) {
            return null;
        }
    }

    public static byte[] assemblyHeadProtocol(short command_type, int total_data_len) {
        
        List<byte[]> protoList = new ArrayList<byte[]>();

        String VERIFY_CODE = "PEOPLE10";
        byte[] verifyCodeByte = VERIFY_CODE.getBytes();//[8]验证码
        byte[] dataLenByte = DataConvert.intToByteArray(total_data_len + 20);//[4]数据总长
        
        short type = 3;  //协议类型
        byte[] protoTypeByte = DataConvert.shortToBytes(type);//[2]协议类型
        byte[] commandTypeByte = DataConvert.shortToBytes(command_type);//[2]命令类型
        byte[] retain_field_16 = new byte[16];//16位保留字段
        
        protoList.add(verifyCodeByte);//[8]验证码
        protoList.add(dataLenByte);//[4]数据总长
        protoList.add(protoTypeByte);//[2]协议类型
        protoList.add(retain_field_16);//[16]保留字段
        protoList.add(commandTypeByte);//[2]命令类型
        byte[] proto = DataConvert.sysCopy(protoList);
        
        System.out.println("最终给的协议数据是:"+new String(proto));
        
        return proto;
    }


服务端解析干货:

/**
     * 接收socket传递来的数据
     */
    public static String accepts() {
        ServerSocket serSocket = null;
        Socket socket = null;
        InputStream ins = null;
        BufferedInputStream bis = null;
        
        byte[] byte_identifyCode = null;
        String resStr = "";
        String verifyCode = "";
        try {
            serSocket = new ServerSocket(PORT);
            socket = serSocket.accept();
            ins = socket.getInputStream();
            bis = new BufferedInputStream(ins, 1024);

            byte_identifyCode = new byte[8];
            int nresult = bis.read(byte_identifyCode, 0, 8);
            if (nresult < 0) {
                System.out.println("读取标准头的前8字节时报错!!");
            }
            verifyCode = new String(byte_identifyCode); // 验证码
      
            byte[] byte_alllen = new byte[4];
            int nresult2 = bis.read(byte_alllen, 0, 4);
            int length = DataConvert.bytesToInt(byte_alllen);

            if (nresult2 < 0) {
                System.out.println("image:对不起,读取标准头的后4个标识长度字节时报错!!");
            }
            
            byte[] protoTypeArr = new byte[2];
            bis.read(protoTypeArr, 0, 2);
            short protoType = DataConvert.bytesToShort(protoTypeArr);
 
            byte[] otherArr = new byte[16];
            bis.read(otherArr, 0, 16);

            byte[] commandTypeArr = new byte[2];
            bis.read(commandTypeArr, 0, 2);
            short commandType = DataConvert.bytesToShort(commandTypeArr);

            byte[] numbyte = new byte[4];
            bis.read(numbyte,0,4);
            int num = DataConvert.bytesToInt(numbyte);

            byte[] lennamebyte = new byte[4];
            bis.read(lennamebyte, 0, 4);
            int len = DataConvert.bytesToInt(lennamebyte);

            byte[] namebyte = new byte[4];
            bis.read(namebyte, 0, 4);
            //String relName =new String(namebyte,"utf-8");
            String relName =new String(namebyte);
              
            byte[] rightbyte = new byte[4];
            bis.read(rightbyte, 0, 4);
            int right = DataConvert.bytesToInt(rightbyte);   
      
            byte[] ismutilbyte = new byte[1];
            bis.read(ismutilbyte,0,1);
            String ismutil = new String(ismutilbyte);
            
            return String.valueOf("OK");
            
        } catch (Exception e) {
            System.out.println("协议解析发生异常:" + e.getMessage());
            resStr = null;
        }finally{
            try {
                if (bis != null) {
                    bis.close();
                }
            } catch (Exception e) {
           }
        }
        return resStr;
    }

 转换的类在:http://blog.youkuaiyun.com/supingemail/article/details/35989103

主意:汉字传输时候,要先传长度,再传汉字。解析时候也是,否则就不能正常解析

想了解更多详细内容:http://download.youkuaiyun.com/detail/supingemail/7602895

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值