今天这个项目需要c服务端与java客户端进行socket通信。
中间遇到了很多问题。
首先搜索了一下
http://blog.sina.com.cn/s/blog_55934df80100i55l.html
有以下几点要注意的地方:
1.大端与小端的转换。具体可以参看这个博客
我的客户端是用c写的,属于小端模式,而TCP和java都是大端模式。所以服务器端在发送int WORD 或者是double等数据类型的时候必须先将小端转换成大端模式,而在接受到数据以后必须将这些类型再重新转换成小端模式。具体转换可以看下面这个列表。
¨ #define ntohs(n) //16位数据类型网络字节顺序到主机字节顺序的转换
¨ #define htons(n) //16位数据类型主机字节顺序到网络字节顺序的转换
¨ #define ntohl(n) //32位数据类型网络字节顺序到主机字节顺序的转换
¨ #define htonl(n) //32位数据类型主机字节顺序到网络字节顺序的转换
2.结构体对齐。具体可以参看这个博客
typedef struct My_Send_Chinese{
byte Type;
WORD size;
char data[4];
}Send_Chinese;
我遇到的问题是这样的。当我在发送数据的时候,我定义了成员Type = 0x 41通过抓包工具发现Type发送过去的数据是0x 41 cc
导致java端接收的时候出错。那么这里为什么会出现一个多出来的cc 呢?
这是结构体对齐所导致的。具体大家可以看上面那个链接。
先让我们看四个重要的基本概念:
1.数据类型自身的对齐值:对于char型数据,其自身对齐值为1,对于short型为2,对于int,float,double类型,其自身对齐值为4,单位字节。
2.结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值。
3.指定对齐值:#pragma pack (value)时的指定对齐值value。
4.数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中小的那个值。
解决的办法是添加下面这句:
#pragma pack (1)
理由就是上面的4条重要规则。