博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Socket网络通讯开发总结之:Java 与 C进行Socket通讯(转)
阅读量:6086 次
发布时间:2019-06-20

本文共 2249 字,大约阅读时间需要 7 分钟。

先交待一下业务应用背景:

服务端:移动交费系统:基于C语言的Unix系统
客户端:增值服务系统:基于Java的软件系统
通迅协议:采用TCP/IP协议,使用TCP以异步方式接入
数据传输:基于Socket流的方式,传输的是网络字节序

Java Socket通讯实现方式这里不做过多的描述,网上到处可以搜索到,比较简单,这里要说的是Java 与 C 进行Socket通讯需注意的地方:

1、Java与C的各种数据类型存储的字节数是不同的:

 Java与C的数据类型的比较  

  Type      Java      C  
  short      2-Byte   2-Byte  
  int        4-Byte   4-Byte  
  long       8-Byte   4-Byte  
  float      4-Byte   4-Byte  
  double     8-Byte   8-Byte  
  boolean    1-bit     N/A  
  byte       1-Byte    N/A  
  char       2-Byte    1-Byte

所以在通讯前,需要进行类型转换,对于C定义的unsign char为一个字节存储,对应Java这边用byte存储;对于C定义的int, long, float对应Java用int存储,具体可以参考以上的表。

2、Socket通讯是按字节传输的(即8个bit位传输),而对于超过一个字节的类型如short 为两个字节,就存在两种传输入方式,一种是高字节在前传输;一种是高字节在后传输。即Little-Endian和Big-Endian。

Little-Endian和Big-Endian是表示计算机字节顺序的两种格式,所谓的字节顺序指的是长度跨越多个字节的数据的存放形式.
        假设从地址0x00000000开始的一个字中保存有数据0x1234abcd,那么在两种不同的内存顺序的机器上从字节的角度去看的话分别表示为:
       1)little endian:在内存中的存放顺序是0x00000000-0xcd,0x00000001-0xab,0x00000002-0x34,0x00000003-0x12
       2)big  endian:在内存中的存放顺序是0x00000000-0x12,0x00000001-0x34,0x00000002-0xab,0x00000003-0xcd
       需要特别说明的是,以上假设机器是每个内存单元以8位即一个字节为单位的.
       简单的说,ittle endian把低字节存放在内存的低位;而big endian将低字节存放在内存的高位.
       现在主流的CPU,intel系列的是采用的little endian的格式存放数据,而motorola系列的CPU采用的是big endian.

网络协议都是Big-Endian的,Java编译的都是Big-Endian的,C编译的程序是与机器相关的,具体是否要进行转换是需要沟通的。假设这里需要转换,以下提供short转的换成字节数组的方式:

 

  public static byte[] ShorttoByteArray(short n) {
    byte[] b = new byte[2];
    b[1] = (byte) (n & 0xff);
    b[0] = (byte) (n >> 8 & 0xff);
    return b;
  }

 

  public static byte[] toLH(short n) {
    byte[] b = new byte[2];
    b[0] = (byte) (n & 0xff);
    b[1] = (byte) (n >> 8 & 0xff);
    return b;
  }
其它的类型转换类似,无非是根据类型在判断用几个字节进行存储而已。

3、由于Socket通讯是按字节进行传输的,而在Java中只有byte是一个字节,故可以将其它类型都转换成byte数组来存储,如:short用两位的字节数组存储,需转换了换以上方法进行,而int用四位的字节数组来存储,对String类型,直接用String.getBytes()来得到它的字节数组。

4、Java的byte与C语言的unsign char虽然都是一个字节存储,但具体的表示内容是不同的,C的无符号char是取值的范围0--255,而Java中byte取值的范围是-128—127,故在实现C语言的字符串时(C是用char[]来表示字符串的),Java这边需要进行转换来模仿C语的unsign char,具体实现函数如下:

  // 将有符号的char转换成无符号的char
  public static char[] ToUnsignedChar(char[] signChar) {
    for (int i = 0; i < signChar.length; i++) {
      int x = ((byte) signChar[i]) >= 0 ? signChar[i] : ((byte) signChar[i]) + 256;
      signChar[i] = (char) x;
    }
    return signChar;
  }
这里的关键点是当signChar[i] < 0时,即加上256,将其转换到0--255中来。

通过以上四个方面的注意,基本上就可以实现Java与C进行Socket通讯了。

转:http://www.linuxidc.com/Linux/2012-06/63173.htm

转载于:https://www.cnblogs.com/guazi/p/6494973.html

你可能感兴趣的文章
Python爬虫之BeautifulSoup
查看>>
《HTML 5与CSS 3权威指南(第3版·下册)》——第20章 使用选择器在页面中插入内容...
查看>>
如何判断自己适不适合做程序员?这几个特点了解一下
查看>>
newinstance()和new有什么区别
查看>>
android下载封装类
查看>>
[node] 用 node-webkit 开发桌面应用
查看>>
Nginx访问控制和虚拟主机
查看>>
report widget not working for external users
查看>>
windows phone 摄像头得到图片是旋转90°
查看>>
Linux--sed使用
查看>>
没有显示器的情况下安装和使用树莓派
查看>>
【android】使用handler更新UI
查看>>
mochiweb 源码阅读(十五)
查看>>
前端面试中的常见的算法问题
查看>>
计算机语言的基本理论
查看>>
nodejs流之行读取器例子
查看>>
批量文件重命名工具
查看>>
简单说一下UWP中的JumpList
查看>>
unity将object[]或者string对象转换成枚举enum
查看>>
PostgreSQL 10.1 手册_部分 II. SQL 语言_第 9 章 函数和操作符_9.19. 范围函数和操作符...
查看>>