Слушатель UDP в C не выводит правильную шестнадцатеричную информацию - PullRequest
0 голосов
/ 08 июня 2018

Я пытаюсь прослушивать определенный порт (6053) и хочу напечатать все данные, поступающие через этот порт.Но я не могу заставить мою программу работать правильно, она выводит ошибочные данные / неверные данные, так как они не совпадают с данными, поступающими из проводной акулы.Если у кого-то есть какие-либо предложения или предложения относительно направления, в которое я должен направиться, это будет очень ценно!

    #include "stdafx.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <WinSock2.h>
    #include <winsock.h>
    #include <string.h>
    #include <sys/types.h>
    #include <assert.h>

int main(void) {
sockaddr_in si_me, si_other;
int s;
assert((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) );//!= -1
int port = 6053;
int broadcast = 1;

setsockopt(s, SOL_SOCKET, SO_BROADCAST,
    (const char * )&broadcast, sizeof broadcast);

memset(&si_me, 0, sizeof(si_me));
si_me.sin_family = AF_INET;
si_me.sin_port = htons(port);
si_me.sin_addr.s_addr = INADDR_ANY;

assert(::bind(s, (sockaddr *)&si_me, sizeof(sockaddr)) );//!= -1

while (1)
{
    char buf[10000];
    int slen = sizeof(sockaddr);
    recvfrom(s, buf, sizeof(buf) - 1, 0, (sockaddr *)&si_other, &slen);

    printf("recv: %x\n", buf);
}

}

Ответы [ 2 ]

0 голосов
/ 08 июня 2018
printf("recv: %x\n", buf);

ожидает, что buf будет int, который печатается в шестнадцатеричном формате.Но buf не является int;это char* (после распада).Таким образом, вы врете printf о типе buf, вызывая неопределенное поведение.Одним из возможных выражений UB будет то, что напечатанное шестнадцатеричное значение - это последние 32 бита адреса вашего буфера, который, безусловно, не будет иметь никакого отношения к полученным данным.

Если бы вы скомпилировали с -Wall, ваш компилятор предупредил бы вас об этом.

Он мог бы также предупредить вас о том, что вы не используете возвращаемое значение recvfrom.Поскольку передачи UDP могут включать байты NUL (и, следовательно, обычно не являются строками C, которые не могут содержать NUL), вам необходимо знать, сколько байтов вы получили.recvfrom предоставляет эту информацию в качестве возвращаемого значения, которое также сообщит вам, произошла ошибка или нет.Нет другого способа узнать, сколько байтов было получено, поэтому использование возвращаемого значения эффективно обязательно.

Поскольку пакет, полученный с помощью recvfrom, не будет завершен NUL, нет смысла резервироватьбайт для завершения NUL;это не будет использоваться.(Если бы вы точно знали, что пакеты являются строками, и вы хотели, чтобы буфер заканчивался NUL, вам придется делать это самостоятельно, используя длину, возвращаемую recvfrom. В этом случае вам нужно будет оставить место длябайт.)

0 голосов
/ 08 июня 2018

Прежде всего, вы не проверяете результат возврата recvfrom, поэтому ваш массив buf может содержать ошибочные данные / неверные данные в точности так, как вы их описали.Не могли бы вы проверить документацию MSDN, например (или любое другое руководство по recvfrom), поскольку оно содержит хорошую отправную точку: https://msdn.microsoft.com/en-us/library/windows/desktop/ms740120(v=vs.85).aspx

...