最近在做java和c的UDP通信,才发现自己的通信基础知识基本为0,汗一个。。不过还好,在大家的帮助下,终于完成了。。下面写下一些小的总结。
(1)字节序问题:这个是通讯的大问题。。前面几篇文章也转载了查阅到的一些资料。总的来说C一般使用的是小尾存储数据,而java使用大尾存储,所谓大尾存储就是数据高字节在前,低字节在后存储。而网络中的数据则都是大尾存储。另字符串在传输过程中不会发生变化,而int,long等数值类型的数据会经过根据大小尾进行存储传输。所以当java与c进行通信的时候,java一段数据基本不用进行大小尾转化,而c收到数据后要进行NToH转化,发送数据的时候也要进行HToN数据转化。再加上字符串,打成包传输即可。
(2)传输包问题:总所周知,传输数据不可能一个字节一个字节发送,没有意义,当然要打成代表一定意义的包进行发送,包就要有包头,包尾。比如下面包的定义:

消息结构

项目

说明

Message Header

消息头(所有消息公共包头)

Message Body

消息体

消息头格式(Message Header)

字段名

字节数

类型

描述

Total_Length

4

Unsigned  Integer

消息总长度(含消息头及消息体)

Command_Id

4

Unsigned Integer

命令或响应类型

Sequence_Id

4

Unsigned Integer

消息流水号,顺序累加,步长为1,循环使用(一对请求和应答消息的流水号必须相同)

Version

4

Unsigned Integer

表示,当前网站与AS核心代码通讯的版本号。目前的版本号为:0x0002

消息体如下:

发送请求:

字段名

字节数

类型

描述

AS服务器名称

22

Octet String

AS服务器名称

机构名称

22

Octet String

机构名称

起始日期

4

Unsigned Integer

证书有效起始日期

结束日期

4

Unsigned Integer

证书有效终结日期

响应

字段名

字节数

类型

描述

AS服务器名称

22

Octet String

AS服务器名称

机构名称

22

Octet String

机构名称

证书路径

128

Unsigned string

证书在本机存储路径

结果值

1

char

0:解析正确,1:解析错误

这样当发送的时候需要把消息头和消息体构建出来,并全部转化成byte数组,再进行传输。
再者对数据包发送的时候,是根据接口文件的。。也就是java和c通讯接口文件,自己定义的了,一致就行。这里面如上面包格式所示,都定义好了每个字段的长度,那么当读取的时候也要根据这个长度进行读取。那么当实际的长度没有这么长怎么办呢?那就需要双方定义好填充字符,是使用空字符('\0')呢,还是空格(' ')呢,c里面读取一般遇到空字符就停止。所以使用空字符会比较普遍一些。当java接收到数据后,也要根据找个字符解析出真正长度的字符串。比如使用下面函数去掉后面的空字符:

  private String getRealData(byte[] temp){
String res = new String(temp);
int end = res.indexOf('\0');
String result = res.substring(0,end);
return result;
}

而java得到包之后,如何得到每个字段呢,这个没有别的办法了,只能一段一段的拷贝了。下面是我使用的拷贝方法:

private String getServerName() {
byte[] temp = new byte[22];
System.arraycopy(this.getRawData(), 1, temp, 0, temp.length);
String encodeStr = getRealData(temp);
return new String(Base64.decode(encodeStr.getBytes()));
}

而c中则使用结构体就可以了。定义好结构体,接受的之后直接接受结构体,然后根据结构体读取,方便快捷,java这方面确实有点麻烦了。
(3)byte,string区别:本来以为传输的时候就是string类型字符串,原来根本不是一回事。网络上传输数据都是字节码,就是我们常说的ascII码的,对应到类型上就是byte类型的。而string只是java中一种对象而已。而且java中编码一般是unicode编码的,要进行和byte类型的转化。int和long类型的也要进行int2byte转化。
接收到数据之后,则要进行byte2int转化。且值得注意的是int转成byte并不是直接字符串的转化,比如123转成字符串就是123,但是转成byte就不是了。它要根据整数123所占的字节,得到每个字节的值,再转成byte数组。常用的转化函数有:

//int2byte
public static byte[] intToByte(int n) {
byte[] b = new byte[4];
b[0] = (byte) (n >> 24);
b[1] = (byte) (n >> 16);
b[2] = (byte) (n >> 8);
b[3] = (byte) (n);
return b;
}
public static void int2byte(int n, byte buf[], int offset) {
buf[offset] = (byte) (n >> 24);
buf[offset 1] = (byte) (n >> 16);
buf[offset 2] = (byte) (n >> 8);
buf[offset 3] = (byte) n;
}
// 字节类型转成int类型
public static int byte2int(byte b[]) {
return b[3] & 0xff | (b[2] & 0xff) << 8 | (b[1] & 0xff) << 16
| (b[0] & 0xff) << 24;
}
//short2byte
public static byte[] short2byte(int n) {
byte b[] = new byte[2];
b[0] = (byte) (n >> 8);
b[1] = (byte) n;
return b;
}
// long到byte的转换
public static byte[] long2byte(long n) {
byte b[] = new byte[8];
b[0] = (byte) (int) (n >> 56);
b[1] = (byte) (int) (n >> 48);
b[2] = (byte) (int) (n >> 40);
b[3] = (byte) (int) (n >> 32);
b[4] = (byte) (int) (n >> 24);
b[5] = (byte) (int) (n >> 16);
b[6] = (byte) (int) (n >> 8);
b[7] = (byte) (int) n;
return b;
}

等等,注意:这里只是进行普通的字节码和数值之间的类型转换,并不进行高低位转化。原因前面已经说过了,java和网络字符是一样的,都是高位前,低位后,所以不用进行转化。

(4)中文传输问题:
网络中传输中文极易出现乱码,那怎么办比较好呢,对了,就是对中文进行编码,常用的是Base64编码。再对编码后数据进行传输,接收到后也要先进行base64解码即可。

C与java通讯小结相关推荐

  1. Java中文编码小结

    Java中文编码小结 1. 只有 字符到字节 或者 字节到字符 的转换才存在编码转码; 2. Java String 采用 UTF-16 编码方式存储所有字符.unicode体系采用唯一的码点表示唯一 ...

  2. Java通讯框架介绍

    Java通讯框架介绍 Java通讯框架,有时也被称为网络服务器,其实就是封装IO操作,并提供更高级的API接口.目前比较流行的框架就是:MINA.Cindy.QuickServer等.前段时间为了缩短 ...

  3. java开发小结:(2006.10.12-future)

    java开发小结:(2006.10.12-future) ================================================ log.debug(StringUtils. ...

  4. Java创建对象小结

    Java SE中必可避免的会学到new关键字(用以创建对象),之后又了解到了克隆以及反射都可以创建对象..今天又学到了静态工厂以及构建器,所以呢,在此做一个小结. 下面我先以创建对象的几种方式开始讲起 ...

  5. java通讯源码_GuQiu-JAVA做的局域网通讯源码

    [实例简介] 一个使用JAVA语言做的局域网即时通讯软件项目,实现了多人局域网通讯,传文件功能!无须专门的服务器,每个窗户端都是服务器,也是客户端,使用SOCKET实现!还使用了自定义的协议,想要学习 ...

  6. zk java数据交互 实例_zookeeper与java交互小结实现示例

    对于学习java的小伙伴们来说,zookeeper一定是不陌生的,你们知道要如何在java中与zookeeper交互小结吗?这次小编就通过一个示例来带大家了解一下吧.import org.apache ...

  7. JAVA捕获异常小结

    上一节的小结: 1.已检查异常一定要处理,即除了RunTimeExceoption之外的异常子类. 2.一种消极的方法是一直向上抛出异常,不在函数本阶段处理,throws给主函数给JVM. 3.一种积 ...

  8. java微信公众平台开发接口_微信公众平台API的Java通讯实现

    微信公众平台 相信大家也不陌生,官方网站提供了一个简单的php程序Demo 因为微信平台采用HTTP方式承载微信的协议,而且不是双向通讯,也就是说只能由微信服务器主动请求我们的服务器.其实当你使用我开 ...

  9. java 通讯机_java 上位机与单片机通过串口485通讯

    java 上位机与单片机通过串口485通讯 java 2020-7-12 下载地址 https://www.codedown123.com/29387.html 上位机与单片机通过串口485通讯 co ...

最新文章

  1. 【ORACLE】碎片整理
  2. java 服务端客户端数据传输出现乱码
  3. __get__,__getattr__和__getattribute方法
  4. matlab png转02,matlab把图片pgm格式转换成png格式
  5. 【转】ARC下dealloc过程及.cxx_destruct的探究
  6. 如何利用计算机多核,如何利用多核电脑实现Matlab的并行运算
  7. 学习的最大动力是想要更加减少重复性工作
  8. WCF Data Services查询
  9. Win7+vmware+xpsp3+vs2010驱动开发环境搭建及调试方法
  10. 华为手机海拔测试软件,华为手机海拔高度测量仪
  11. 微软2022年10月补丁周二修复了84个漏洞
  12. smartsvn 忽略文件夹_设置SVN忽略文件和目录(文件夹)
  13. win10提升性能的服务器,win10专业版设置优化提高系统性能图解
  14. Linux学习之——/etc/sysconfig目录
  15. 微信登陆的LOL只有一个服务器,lol微信登录_lol能用微信登录吗_lol微信登录只有一个区-站长之家...
  16. bats指哪几家公司_用BATS测试Bash
  17. 卫生部拟规定就业入学等常规体检不再查乙肝
  18. 编程学习文档 参考资料和文档
  19. jis拉伸试棒图纸_拉伸试棒延伸率快速测量装置制造方法
  20. 三十多岁女计算机考研,三十岁考研女

热门文章

  1. 许耀武:有趣有挑战的二十年
  2. video_replay如何捕获和回放WebRTC视频流
  3. 从C++转向最受欢迎的Rust语言
  4. 大型前端项目的断点调试共享化和复用化实践
  5. nginx_rtmp中解析sps和pps
  6. Kubernetes 1.9 发布
  7. OpenShift安装
  8. 分布式系统原理 之9 CAP 理论
  9. css鼠标悬停样式_利用Css3样式属性Cursor来更换自定义个性化鼠标指针(光标
  10. 使用memcache缓存