我正在尝试侦听特定端口(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);
}
}
答案 0 :(得分:0)
首先,您不检查recvfrom
的返回结果,因此您的buf
数组可能包含与您描述的完全错误的数据/错误数据。你可以查看MSDN文档(或任何其他recvfrom手册),因为它包含一个很好的起点:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms740120(v=vs.85).aspx
答案 1 :(得分:0)
printf("recv: %x\n", buf);
期望buf
为int
,以十六进制表示法打印。但buf
不是int
;它是char*
(衰变后)。因此,您对printf
的{{1}}类型撒谎,导致未定义的行为。 UB的一个可能表达式是打印的十六进制值是缓冲区的地址的最后32位,这肯定不会与接收到的数据有任何关系。
如果您使用buf
进行编译,您的编译器会向您发出警告。
它可能还警告过您没有使用-Wall
的返回值这一事实。由于UDP传输可能包含NUL字节(因此通常不是C字符串,不能包含NUL),因此您需要知道收到的字节数。 recvfrom
提供该信息作为其返回值,该信息还将告诉您是否存在错误。没有其他方法可以知道接收了多少字节,因此有效地使用返回值。
由于recvfrom
接收的数据包不会被NUL终止,因此没有必要为NUL终止保留一个字节;它不会被使用。 (如果您知道数据包是字符串并且您希望缓冲区是NUL终止的事实,则必须使用recvfrom
返回的长度自己执行此操作。在这种情况下,您需要离开字节的空间。)