【问题标题】:Send other data types in winsock2在winsock2中发送其他数据类型
【发布时间】:2011-10-31 23:30:26
【问题描述】:

winsock2 中的发送函数只接受字符指针。 我如何也通过它发送整数或对象?

【问题讨论】:

    标签: c++ windows tcp winsock2


    【解决方案1】:

    const char *buf 您需要作为参数传递给send() 函数只是一个指向字节数组的指针。您需要将整数转换为字节:

    const int MAX_BUF_SIZE = 1024;
    int int_data = 4;
    const char *str_data = "test";
    
    char *buf = (char*) malloc(MAX_BUF_SIZE);
    char *p = buf;
    
    memcpy(&int_data, p, sizeof(int_data));
    p += sizeof(int_data);
    
    strcpy(p, str_data);
    p += strlen(str_data) + 1;
    
    send(sock, buf, p - buf, 0);
    
    free(buf);
    

    和阅读代码:

    const int MAX_BUF_SIZE = 1024;
    int int_data = 0;
    const char *str_data = NULL;
    
    char *buf = (char*) malloc(MAX_BUF_SIZE);
    char *p = buf;
    
    recv(sock, buf, MAX_BUF_SIZE, 0);
    
    memcpy(p, &int_data, sizeof(int_data));
    p += sizeof(int_data);
    
    str_data = malloc(strlen(p) + 1);
    strcpy(str_data, p);
    p += strlen(p) + 1;
    
    free(buf);
    

    而复杂对象需要serialized 才能成为字节流。

    注意 1:如果服务器和客户端都使用相同的平台 (x32 / x64 / ...),则代码示例有效,这意味着 int 具有相同的字节数并且字节顺序相同。

    注意 2:编写代码应检查每一步是否存在缓冲区 (MAX_BUF_SIZE) 溢出。

    【讨论】:

    • 对于整数我应该使用 reinterpret_cast(i) 吗?
    • "(这很容易)" - 对于那些知道如何做的人。如果你必须问这个问题,你不会找到htonshtonl()。 (@Pilpel:“hton”代表“Host TO Network”;它更改字节顺序以匹配 TCP/IP 的顺序。接收时,您将使用“ntoh”函数。两者都存在于 's' 中(简称, 16 bits) 和 'l' (long, 32 bits) 版本。
    • 这如何回答我的问题? ntoh 函数不采用 char 指针并使它们成为整数
    • @Pilpel:不直接。这是你在reinterpret_cast<char*>(&result_of_htonl)之前需要做的步骤
    • 我明白了。所以 hton 中的“主机”这个词既可以是客户端代码,也可以是服务器代码,对吧?
    【解决方案2】:

    只需将值存储到变量中,然后将变量类型转换为char*send()recv() 函数对二进制数据进行操作,尽管采用 char* 参数。

    发送:

    int int_data = 4;
    send(sock, (char*) &int_data, sizeof(int), 0);
    

    阅读:

    int int_data;
    recv(sock, (char*) &int_data, sizeof(int), 0);
    

    【讨论】:

      【解决方案3】:

      通常,最简单的方法是将整数或对象打印到字符串中,然后发送该字符串。文本表示更便携,也更容易调试。

      std::stringstream 可能是一个有用的类,既可以创建字符串,也可以在另一端解析它。

      【讨论】:

      • 这个序列化无效。只要您不需要跨平台可移植性,您就可以使用 memcpy 语义。获取对象的地址及其大小,并将地址和大小传递给 winsock 函数。你需要一个演员在这里。当您的数据包含指向其他对象的指针时,您不能使用 memcpy 样式。在这种情况下,您需要序列化。
      • 无效?你甚至承认它是跨平台的,所以它肯定可以工作。
      • 所以假设我有一个具有两个数据成员 x 和 y 的对象,当 x = 10 和 y = 20 时。您是否建议我将其作为纯文本发送:“10|20” ?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-08
      • 1970-01-01
      • 2016-03-10
      • 1970-01-01
      • 2011-08-16
      • 1970-01-01
      相关资源
      最近更新 更多