【发布时间】:2021-02-01 03:19:54
【问题描述】:
我正在尝试在 C 中通过网络发送一个整数(更具体地说,uint32_t 字节)。根据 Stack Overflow 上的其他示例和答案,我相信我正确地发送了数据;但是,在接收字节时,我无法在不破坏 strict aliasing rule 的情况下将它们转换/转换为 uint32_t。这是我最初尝试的一个例子:
发件人:
uint32_t num = htonl(100);
char* converted_num = (char*)#
send(client_sock, converted_num, sizeof(num), 0);
接收者:
char buf[8192];
recv(socket, buf, 8192, 0);
uint32_t test = ntohl(*(uint32_t*)&buf);
printf("%d\n", (int)test);
虽然这似乎可行,但我收到反馈,uint32_t test = ntohl(*(uint32_t*)&buf); 行违反了严格的别名规则。这是我修复严格混叠违规的尝试:
char buf[8192];
recv(socket, buf, 8192, 0);
uint32_t test = ntohl(*(uint32_t*)memcpy(&(uint32_t){0}, &buf[0], sizeof(uint32_t)));
printf("%d\n", (int)test);
这会导致程序崩溃,即我的问题是如何在 c (windows) 中通过套接字传输整数时最有效地避免违反严格的别名规则。
【问题讨论】:
-
小花絮:将数组大小传递给函数时,请尝试使用
sizeof推导它,以避免输入两次相同的幻数(8192):recv(socket, buf, sizeof buf, 0); -
您的反馈是错误的——因为数据是用
char类型写入的(不是从其他类型复制的),它没有有效类型,所以自动获取读取它的有效类型。没有严格的别名违规。 -
@ChrisDodd 您的反馈是错误的,它是一个 char 数组,有效类型的东西不能像那样工作。此外,更完整的程序也可能具有未对齐的访问权限,而这些才是真正的无声杀手。
-
@AnttiHaapala:数据是
recv写的,所以没有有效类型。根据 6.5 的任何时候,您将数据复制为chars,它保持相同的有效类型,它不会获得char的有效类型。对齐可能是个问题,但与严格的别名无关。 -
你使用什么协议? 'client_sock' 建议使用 TCP,在这种情况下,您发布的代码无论如何都会被破坏。
标签: c windows sockets integer winsock