当前位置: 技术问答>linux和unix
一个socket编程中强制类型转换的疑惑
来源: 互联网 发布时间:2016-09-19
本文导语: 最近在看socket编程, 有个小问题, 请指教, 万分感激 这两个结构的定义: struct sockaddr_in { sa_family_t sin_family; in_port_t sin_port; struct in_addr sin_addr; }; struct sockaddr { sa_family_t sa_family; char sa_data[14]; }; st...
最近在看socket编程, 有个小问题, 请指教, 万分感激
这两个结构的定义:
struct sockaddr_in {
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
};
struct sockaddr {
sa_family_t sa_family;
char sa_data[14];
};
struct sockaddr_in saddr;
bind(sock_id, (struct sockaddr *)&saddr, ...
这个bind中的强制类型转换, 感觉十分别扭.
按我的认识, 这样强制转换后的指针, 可以正常访问sa_family, 而把sizeof(in_port_t)个字节的sin_port挨个放到sa_data里, 以及sin_addr也拆成一个一个字节放到sa_data中.
这? 明显说不通嘛.
为什么两个不同类型的指针转换后为什么还能正常工作啊?
这两个结构的定义:
struct sockaddr_in {
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
};
struct sockaddr {
sa_family_t sa_family;
char sa_data[14];
};
struct sockaddr_in saddr;
bind(sock_id, (struct sockaddr *)&saddr, ...
这个bind中的强制类型转换, 感觉十分别扭.
按我的认识, 这样强制转换后的指针, 可以正常访问sa_family, 而把sizeof(in_port_t)个字节的sin_port挨个放到sa_data里, 以及sin_addr也拆成一个一个字节放到sa_data中.
这? 明显说不通嘛.
为什么两个不同类型的指针转换后为什么还能正常工作啊?
|
这个问题是socket编程系列接口中定义的数据结构决定的。下面是地址in的一个结构
typedef struct in_addr {
union {
struct { UCHAR s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { USHORT s_w1,s_w2; } S_un_w;
ULONG S_addr;
} S_un;
#define s_addr S_un.S_addr /* can be used for most tcp & ip code */
#define s_host S_un.S_un_b.s_b2 // host on imp
#define s_net S_un.S_un_b.s_b1 // network
#define s_imp S_un.S_un_w.s_w2 // imp
#define s_impno S_un.S_un_b.s_b4 // imp #
#define s_lh S_un.S_un_b.s_b3 // logical host
} IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;
在bind(sock_id, (struct sockaddr *)&saddr中,你输入的地址存储的内容,按照几个字节的次序,是完全一致的,所有效果是一样。
比如:
int a=0x12345678;
unsigned char *pC=(unsigned char *)&a;
*pC对应的位置就是0x78;(这里指PC机上字节次序)
*(pC+1)对应的位置就是0x56;
*(pC+2)对应的位置就是0x34;
*(pC+3)对应的位置就是0x12;
typedef struct in_addr {
union {
struct { UCHAR s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { USHORT s_w1,s_w2; } S_un_w;
ULONG S_addr;
} S_un;
#define s_addr S_un.S_addr /* can be used for most tcp & ip code */
#define s_host S_un.S_un_b.s_b2 // host on imp
#define s_net S_un.S_un_b.s_b1 // network
#define s_imp S_un.S_un_w.s_w2 // imp
#define s_impno S_un.S_un_b.s_b4 // imp #
#define s_lh S_un.S_un_b.s_b3 // logical host
} IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;
在bind(sock_id, (struct sockaddr *)&saddr中,你输入的地址存储的内容,按照几个字节的次序,是完全一致的,所有效果是一样。
比如:
int a=0x12345678;
unsigned char *pC=(unsigned char *)&a;
*pC对应的位置就是0x78;(这里指PC机上字节次序)
*(pC+1)对应的位置就是0x56;
*(pC+2)对应的位置就是0x34;
*(pC+3)对应的位置就是0x12;