读书人

Java 与 C进展Socket通讯

发布时间: 2012-09-25 09:55:59 作者: rapoo

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通讯了。

读书人网 >编程

热点推荐