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;

JAVA服务器与C#客户端的通信技术调研的更多相关文章

  1. Java和Android Http连接程序:使用java.net.URL 下载服务器图片到客户端

    Java和Android Http连接程序:使用java.net.URL 下载服务器图片到客户端 本博客前面博文中利用org.apache.http包中API进行Android客户端HTTP连接的例子 ...

  2. 在C#客户端用HTTP上传文件到Java服务器

    在C#客户端用HTTP上传文件到Java服务器  来源:http://www.cnblogs.com/AndyDai/p/5135294.html 最近在做C / S 开发,需要在C#客户端上传文件到 ...

  3. Java Socket实现HTTP客户端来理解Session和Cookie的区别和联系

    HTTP协议本身是无状态的,即使是同一台电脑同一个浏览器打开同一个页面两次,服务器不知道这两次请求是同一个客户端发送过来的,两次请求是完全独立的.例如,第一次请求时已经登录了,第二次再请求服务器会“忘 ...

  4. SLG手游Java服务器的设计与开发——架构分析

    微信公众号[程序员江湖] 作者黄小斜,斜杠青年,某985硕士,阿里 Java 研发工程师,于 2018 年秋招拿到 BAT 头条.网易.滴滴等 8 个大厂 offer,目前致力于分享这几年的学习经验. ...

  5. Java泛型与Restlet客户端

    写一个与restlet服务器通信的客户端类,用于测试通信是否成功,并且进行交互.为了方便其他人使用,于是,写一个通用的方法封装起来,可是中途却放生了一些问题. 按照正常写法,顺序走下来是这样的: pu ...

  6. Java实验五(客户端)

    一.    实验内容 1.    运行教材上TCP代码,结对进行,一人服务器,一人客户端: 2.    利用加解密代码包,编译运行代码,客户端加密,服务器解密: 3.    客户端加密明文后将密文通过 ...

  7. SLG手游Java服务器的设计与开发——数据管理

    文章版权归腾讯GAD所有,禁止匿名转载:禁止商业使用:禁止个人使用. 一.前言 上文介绍了我们的SLG手游的服务器架构设计以及网络通信部分,本文介绍数据管理部分,在数据存储方面,我选择了Mysql.M ...

  8. Cloudera Manager安装之时间服务器和时间客户端(Ubuntu14.04)(二)

    第二步: Cloudera Manager安装之时间服务器和时间客户端(二) 找一台机器作为时间服务器 我这里,放到ubuntucmbigdata1这台机器! 注意,之前是已经做了集群时间同步了. 在 ...

  9. java集成jpush实现客户端推送

    代码地址如下:http://www.demodashi.com/demo/13700.html 前言 java 集成jpush 实现客户端推送 一.准备工作 开发环境: jdk1.6 Eclipse ...

随机推荐

  1. Python在pycharm中编程时应该注意的问题汇总

    1.缩进问题 在 pycharm 中点击 enter 自动进行了换行缩进,此时应该注意:比如 if   else  语句,后面跟着打印输出 print 的时候,一定注意是要if语句下的输出还是else ...

  2. bat cmd dos 通过拖拽参数 上传 截取拖拽上传文件名

    echo off setlocal enabledelayedexpansion :: L 小写 for /l %%i in (1,1,10000) do ( :con set /p a= selec ...

  3. Mysql delete操作

    以下摘自官方文档:https://dev.mysql.com/doc/refman/5.7/en/insert.html 语法: DELETE [LOW_PRIORITY] [QUICK] [IGNO ...

  4. lua 中的点、冒号与self

    [lua 中的点.冒号与self] lua编程中,经常遇到函数的定义和调用,有时候用点号调用,有时候用冒号调用. girl = {money = 200} function girl.goToMark ...

  5. mysql开通tcp远程连接

    1.登陆mysql: mysql -u root mysql 2.运行下面命令 UPDATE `mysql`.`user` SET `Host` = '%' WHERE `user`.`Host` = ...

  6. tf.unstack\tf.unstack

    tf.unstack 原型: unstack( value, num=None, axis=0, name='unstack' ) 官方解释:https://tensorflow.google.cn/ ...

  7. [leetcode]236. Lowest Common Ancestor of a Binary Tree 二叉树最低公共父节点

    Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According ...

  8. [leetcode]215. Kth Largest Element in an Array 数组中第k大的元素

    Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...

  9. 什么是Shell、Shell脚本

    Shell本身是一个用C语言编写的程序,它是用户使用Linux的桥梁.Shell既是一种命令语言,又是一种程序设计语言.作为命令语言,它交互式地解释和执行用户输入的命令:作为程序设计语言,它定义了各种 ...

  10. Spring框架的特点

    1. 为什么要学习Spring的框架 * 方便解耦,简化开发 * Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理 * AOP编程的支持 * Spring提供面向切面 ...