【问题标题】:Send string with binary null '\0'发送带有二进制 null '\0' 的字符串
【发布时间】:2011-05-30 07:02:31
【问题描述】:

您好,我编写了以 udp 数据包发送文件的 linux 守护程序。 问题是在字符串"abc\0asdf" 中它只发送abc 而不是空字符和asdf(空符号后的所有字符),

有udp客户端代码,发送数据包:

int sock;
    struct sockaddr_in server_addr;
    struct hostent *host;
    host= (struct hostent *) gethostbyname((char *)ip);
    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1){
        perror("socket");
        exit(1);
    }
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);
    server_addr.sin_addr = *((struct in_addr *)host->h_addr);
    memset(server_addr.sin_zero,0,8);

以及发送缓冲区的代码:

if (sendto(sock, buf, sizeof buf, 0, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))==-1)

在服务器端我需要接收二进制缓冲区:

定义套接字代码:

int sock;
    int addr_len, bytes_read;
    struct sockaddr_in server_addr , client_addr;
    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        perror("Socket");
        exit(1);
    }
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);
    server_addr.sin_addr.s_addr = INADDR_ANY;
    //bzero(&(server_addr.sin_zero),8);
    memset(server_addr.sin_zero,0,8);
    if (bind(sock,(struct sockaddr *)&server_addr,
    sizeof(struct sockaddr)) == -1){
        perror("Bind");
        exit(1);
    }
    addr_len = sizeof(struct sockaddr);

                            diep("sendto()");

并接收缓冲区(在大循环中):

bytes_read = recvfrom(sock,buf,sizeof (buf),0,
            (struct sockaddr *)&client_addr, &addr_len);

有人知道为什么我没有收到完整的缓冲区吗?

【问题讨论】:

  • 你如何验证buf的内容? bytes_read 的值与sendto 的返回值是多少?
  • sender返回发送5000字节,receive返回读取5000字节,buf大小为500字节。
  • sorry buf size也定义为5000字节
  • @crab,你的问题是什么?你得到的正是你发送的数据量
  • @crab,我猜,你会有一个printf("%s",buf); 声明来验证你的问题。它最多只能读取\0

标签: c linux udp


【解决方案1】:

通过查看 cmets,错误很可能是您将接收到的缓冲区视为字符串。

如果要打印/输出缓冲区,则需要先将空字符转换为其他字符。

【讨论】:

    【解决方案2】:

    您应该使用 for 循环而不是 printf 来打印接收到的缓冲区:

     for (int i=0; i<bytes_read; i++)
         printf("%c",buf[i]);
    

    【讨论】:

      【解决方案3】:

      这是不正确的(格式已更改,因此适合我的屏幕):

      if (sendto(sock,
                 buf,
                 sizeof buf,
                 0,
                 (struct sockaddr *)&server_addr,
                 sizeof(struct sockaddr))==-1)
      

      您希望sizeof(server_addr) 作为长度。这将大于sizeof(struct sockaddr)

      另外,从手册页:

      返回值 成功时,这些调用返回发送的字符数。出错时返回 -1,并适当设置 errno。

      您还没有考虑到它返回的值小于sizeof(buf) 的情况。不知道这是怎么发生的,但它似乎是可以处理的。

      我对整体方法的评论类似于@jgauffin 所说的。 buf 只是字节。 '\0' 终止它们只是 C 字符串的约定,而不是要求。通常在使用二进制字节缓冲区时,您还会跟踪大小。您只是假设将使用所有sizeof(buf),这是没有意义的。 (建议:也许您的sendto 有效负载的一部分应该包括后面的消息的大小?)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-08-10
        • 2013-02-28
        • 1970-01-01
        • 1970-01-01
        • 2023-03-12
        • 2011-07-11
        • 2017-04-25
        相关资源
        最近更新 更多