所以我在这里构建基于字节数组的short / longs,我想避免使用memcpy
将字节复制到它们自己的变量中,然后将该变量赋值给sockaddr_in
对象。
有没有更好的方法在以下语句中提取short
?:
((sockaddr_in*)from)->sin_port = (*((unsigned short*)&buf[4]));
我做了整个指针/解引用的事情,因为如果我的逻辑是正确的,只做一个(unsigned short)buf[4]
强制转换将只转换一个字节;不是两个。
memcpy
之外。
答案 0 :(得分:2)
您问题中的代码:
(*((unsigned short*)&buf[4]))
由于以下问题,可能无效:
如果您对字节序有信心,那么 memcpy
是安全的(如果没有,那么您应该与ntohs
或ntohl
结合使用)。一个不错的编译器也应该优化它。
如果你真的想避免使用memcpy
,那么安全,独立于平台的方式类似于以下内容(假设buf
最初是使用标准网络字节顺序从外部源填充的) :
((buf[n] << 8) | buf[n+1])
当然,你应该将它包装在一个函数中(如果你必须的话,还是一个宏)。
答案 1 :(得分:1)
我认为在任何情况下,正确的解决方案都是使用ntohs
和htons
等功能(long
使用ntohl
和htonl
)。
((sockaddr_in*)from)->sin_port = htons(*((unsigned short*)&buf[4]));
另请注意,根据字节数组的来源,您可能会遇到其他Endianess问题。
对齐可能是某些体系结构(HP-RISC,SPARC)的另一个问题。函数memcpy
和memmove
通常没有这些问题。 你不应该过早优化!
答案 2 :(得分:0)
您可以使用ntohs宏来处理字节顺序转换,htons表示主机到网络的顺序
((sockaddr_in*)from)->sin_port = htons(*((uint16_t*)&buf[4]));
请注意,但是某些体系结构不允许未对齐访问,因此您需要确保它已对齐,或者您可能需要将对齐的字节提取到临时变量中并相应地对位进行随机播放。