zoukankan      html  css  js  c++  java
  • JAVA服务器与C#客户端的通信技术调研

    JAVA服务器与C#客户端的通信技术调研

    研究背景及目的:

    ARPG项目的需求:需要将现有的服务器从C++的编写平台换为java语言。
    在对需求进行分析的过程中,发现几点需要研究实现的问题

    1. java与c+语言特性迥异,相比c+ 和c#关系的密切性,java需要对c#风格的一些数据结构和编码格式进行兼容;
    2. c#拥有的无符号数据类型如 ushort unint java并不存在,需要对数据类型进行转换;
    3. 根据开发需要 客户端现有的通信协议不能更改,所以在java中进行各类型的兼容操作
    4. 在项目中底层通信报文的类 是由名叫PROTOGEN的现有工程进行生成,生成方式是以生成字符串文本类的方式,原工程已经可以同时生成c#及c++的类(.cs及.h文件),但并没有生成迁移后的服务器java的相关代码和类的功能。故需要二次开发。

    工作任务:

    综上所述,工作任务有两点:

    1. 重构java的 数据流输入和输出类,使其兼容c#客户端传输过来的 二进制数据结构;(以下简称PJIO)
    2. 对PROTOGEN进行二次开发,使其能够生成java的 底层协议类(.java文件),并不破坏其现有生成其他语言的类的功能;(以下简称PGPLUS)
    3. 进行测试和验证,确保前两项工作任务的有效和后续开发工作的顺利开展。

    工作开展中遇到的技术问题和技术细节:

    PJIO:
    1. 在测试和开发过程中,通过查阅资料,发现c#和C++的数据存储格式为小端类型而java是大端类型(即字节序问题)

    在几乎所有的机器上,多字节对象都被存储为连续的字节序列。例如在C语言中,一个类型为int的变量x地址为0x100,那么其对应地址表达式&x的值为0x100。且x的四个字节将被存储在存储器的0x100, 0x101, 0x102, 0x103位置。[1]
    而存储地址内的排列则有两个通用规则。一个多位的整数将按照其存储地址的最低或最高字节排列。如果最低有效位在最高有效位的前面,则称小端序;反之则称大端序。在网络应用中,字节序是一个必须被考虑的因素,因为不同机器类型可能采用不同标准的字节序,所以均按照网络标准转化。
    例如假设上述变量x类型为int,位于地址0x100处,它的十六进制为0x01234567,地址范围为0x100~0x103字节,其内部排列顺序依赖于机器的类型。大端法从首位开始将是:0x100: 01, 0x101: 23,..。而小端法将是:0x100: 67, 0x101: 45,..。

    大端序

    大端序(英:big-endian)或称大尾序

    • 数据以8bit为单位:

      地址增长方向  →

      ...

      0x0A

      0x0B

      0x0C

      0x0D

      ...

      示例中,最高位字节是0x0A 存储在最低的内存地址处。下一个字节0x0B存在后面的地址处。正类似于十六进制字节从左到右的阅读顺序。

    • 数据以16bit为单位:

      地址增长方向  →

      ...

      0x0A0B

      0x0C0D

      ...

      最高的16bit单元0x0A0B存储在低位。

      小端序

      小端序(英:little-endian)或称小尾序
    • 数据以8bit为单位:

      地址增长方向  →

      ...

      0x0D

      0x0C

      0x0B

      0x0A

      ...

      最低位字节是0x0D 存储在最低的内存地址处。后面字节依次存在后面的地址处。

    • 数据以16bit为单位:

      地址增长方向  →

      ...

      0x0C0D

      0x0A0B

      ...

      最低的16bit单元0x0D0C存储在低位。

    • 更改地址的增长方向:

    当更改地址的增长方向,使之由右至左时,表格更具有可阅读性。

    ←  地址增长方向

    ...

    0x0A

    0x0B

    0x0C

    0x0D

    ...

    最低有效位(LSB)是0x0D 存储在最低的内存地址处。后面字节依次存在后面的地址处。

    ←  地址增长方向

    ...

    0x0A0B

    0x0C0D

    ...

    最低的16bit单元0x0C0D存储在低位。 
    本部分具体内容详见https://zh.wikipedia.org/wiki/%E5%AD%97%E8%8A%82%E5%BA%8F
    所以在PJIO中对报文对象进行传输之前和接收报文之后 都会对报文的BYTE数组进行反转,以兼容c#的字节序,这也是对java的输入输出流进行重构的主要目的;

    1. java并不包含无字符数 所以全由对应宽度(字节长度)的数进行代替;

    例如 ushort>>short;

    PGPLUS:

    1,这个项目主要是遇到一个问题,java 不能在同一个文件里 生成多个公共类
    还有关于驼峰式命名法的 语言规范与C#不同。C#函数首字母大写,比如a.ReadInt16();
    Java中的方法(函数)首字母要小写即 a.readInt16();

    1. 关于枚举,c#中枚举可以赋予初始值例如: 

    而java 则不允许,如果非要实现:结果很不令人满意
    所以枚举统一转换成仅含有常量的公共类


    如上图

    暂时未解决的问题:

    java在读取c#传输过来的报文的时候 后面会有两个字节的0;

  • 相关阅读:
    解决SharePoint 文档库itemadded eventhandler导致的上传完成后,编辑页面保持报错的问题,错误信息为“该文档已经被编辑过 the file has been modified by...”
    解决SharePoint 2013 designer workflow 在发布的报错“负载平衡没有设置”The workflow files were saved but cannot be run.
    随机实例,随机值
    Spring4笔记
    struts2笔记(3)
    struts2笔记(2)
    获取文本的编码类型(from logparse)
    FileUtil(from logparser)
    DateUtil(SimpleDateFormat)
    struts2笔记
  • 原文地址:https://www.cnblogs.com/hellohuan/p/6068519.html
Copyright © 2011-2022 走看看