发送二进制空字符串'\ 0'

问题描述 投票:2回答:3

嗨,我编写了linux守护程序,用于发送udp数据包中的文件。问题是在字符串"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);

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

c linux udp
3个回答
2
投票

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

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


2
投票

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

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

你想要sizeof(server_addr)作为长度。这将大于sizeof(struct sockaddr)

另外,从手册页:

Return Value On success, these calls return the number of characters sent. On error, -1 is returned, and errno is set appropriately.

你还没有考虑到它返回的值低于sizeof(buf)的情况。不知道如何发生这种情况但似乎有待处理。

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


1
投票

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

 for (int i=0; i<bytes_read; i++)
     printf("%c",buf[i]);
© www.soinside.com 2019 - 2024. All rights reserved.