Отправить строку с двоичным нулем '\ 0' - PullRequest
2 голосов
/ 30 мая 2011

Привет! Я запрограммировал демона 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);

Кто-нибудь знает, почему я не получил полный буфер?

Ответы [ 3 ]

2 голосов
/ 30 мая 2011

Вы должны использовать цикл for для печати полученного буфера вместо printf:

 for (int i=0; i<bytes_read; i++)
     printf("%c",buf[i]);
2 голосов
/ 30 мая 2011

Это неверно (форматирование изменено, поэтому оно умещается на экране):

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

Вы хотите sizeof(server_addr) в качестве длины. Это будет больше, чем sizeof(struct sockaddr).

Также с man-страницы:

Возвращаемое значение В случае успеха эти вызовы возвращают количество отправленных символов. При ошибке возвращается -1, и errno устанавливается соответствующим образом.

Вы не учли случай, когда он возвращает значение, меньшее sizeof(buf). Не уверен, как это может произойти, но, похоже, что-то нужно для этого сделать.

Мой комментарий к общему подходу похож на то, что говорит @jgauffin. buf это просто байты. Это только соглашение для строк C, что '\0' завершает их, а не требование. Обычно при использовании двоичных байтовых буферов вы также отслеживаете размер. Вы просто предполагаете, что будут использованы все sizeof(buf), что не имеет смысла. (Предложение: Возможно, часть вашей sendto полезной нагрузки должна включать в себя размер следующего сообщения?)

2 голосов
/ 30 мая 2011

Глядя на комментарии, наиболее вероятно, что вы воспринимаете полученный буфер как строку.

Если вы хотите напечатать / вывести буфер, вам нужно сначала преобразовать нулевой символ во что-то другое.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...