我在这个例子中找到了以下代码:
addr.sin_addr.s_addr = *(long *)(host->h_addr);
Run Code Online (Sandbox Code Playgroud)
h_addris是一个char指针,host是指向类型结构的指针hostent.addr是类型的结构sockaddr_in和sin_addr类型是一个结构in_addr.s_addr是一个uint32.
大部分信息可以在这里找到:http://man7.org/linux/man-pages/man7/ip.7.html
我很确定(long)将char转换为long,但我不知道这些额外的星号是做什么的,特别是因为s_addr它不是指针.
有人能解释一下这里发生了什么吗?
(long *)(host->h_addr)意思是解释host->h_addr为指向a的指针long.这不是很便携,但据推测long,这个系统的长度是32位.
另外一个明星在*(...)解除引用现在的long任务.这有效地将原始char数组的所有四个字节复制到单个long值中addr.sin_addr.s_addr.比较(long)(*host->h_addr),只会复制第一个char元素.
这种技术非常难以移植.它假设该long类型的大小和字节序.你可能会从一个事实,即一个暗示s_addr是uint32,做:
addr.sin_addr.s_addr = *(uint32_t *)(host->h_addr);
Run Code Online (Sandbox Code Playgroud)
这并不是更好,因为字节序仍然受到破坏.此外,uint32_t保证至少保持32位.它可以是任何更大的位数,当您尝试使用副本读取未分配的内存时,会调用未定义的行为(想象将32位char数据复制为64位整数).
未来有两种选择:
如果您的char数组已经是正确的字节顺序(即,您不关心是否h_addr[0]表示本地的最高或最低字节uint32_t),请使用memcpy:
memcpy(&(addr.sin_addr.s_addr), host->h_addr, 4);
Run Code Online (Sandbox Code Playgroud)
这可能是您需要的方法.另一方面,如果您希望h_addr[0]始终以最高字节结束,则需要尊重系统的字节顺序:
addr.sin_addr.s_addr = (host->h_addr[0] << 24) + (host->h_addr[1] << 16) + (host->h_addr[2] << 8) + (host->h_addr[3]);
Run Code Online (Sandbox Code Playgroud)
在那里可能需要有一些演员阵容uint32_t.
| 归档时间: |
|
| 查看次数: |
286 次 |
| 最近记录: |