在 c 中通过 windows 套接字发送整数

Sending integer over windows socket in c

我正在尝试用 C 通过网络发送一个整数(更具体地说,uint32_t 字节)。根据 Stack Overflow 上的其他示例和答案,我相信我发送的数据是正确的;但是,在接收字节时,我遇到了 casting/converting 到 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);

接收器输出一个大整数 1755042816 而不是正确的整数值“100”。我做错了什么?

在这一行

    uint32_t test = ntohl((uint32_t)&buf);

您正在转换并打印指向 buf 的指针,而不是接收到的数据。 取消引用指针以获取接收到的内容。

    uint32_t test = ntohl(*(uint32_t*)&buf);

您将指针转换为一个无效的整数。 *(uint32_t*)&buf 如果你幸运的话可能 工作,但由于严格的别名违规,它是 undefined-behavior C。

为了正确起见,您应该先 memcpy 到一个 uin32_t,然后再将 nthol 应用到那个。

static inline uint32_t ntohl_ch(char const *X)
{
    uint32_t x; memcpy(&x,X,sizeof(x));
    return ntohl(x);
}

//...
    uint32_t test = ntohl_ch(&buf[0]);
//...

严格别名允许您将任何对象视为 char(或 signed charunsigned char)的数组。反之则不然。在 char 数组中想象 uint32_t 是不允许的,您必须使用 memcpy.

优化编译器会注意到你 memcpy 只是一个 uint32_t 并省略了一个完整的 memcpy 调用(支持直接 mov 注册或直接应用a 原始内存上的汇编指令)。