4

我正在尝试构建一个将通过 UDP 发送的数据包。但是,我没有在接收方获得正确的数据。

在数据包中,我想包含一个 IP 标头、UDP 标头和需要发送的数据。在这种情况下,我只想发送单词“Hello”以及随机标题信息。

char *data = "Hello";
char *packet = (char *)malloc(sizeof(struct iphdr) + sizeof(struct udphdr) + strlen(data));
struct iphdr *ip = (struct iphdr*) packet;
struct udphdr *udp = (struct udphdr*) (packet + sizeof(struct iphdr));
char *send_buff = (char *) (packet + sizeof(struct iphdr) + sizeof(struct udphdr));
ip->saddr = inet_addr("1.2.3.4");
ip->daddr = inet_addr("5.6.7.8");
ip->ttl = 5;
udp->source = 5950;
udp->dest = 5950;
udp->len = sizeof(struct udphdr);
udp->check = 0;
strcpy(send_buff, data);

sendto(sock, packet, (sizeof(struct iphdr) + sizeof(struct udphdr) + strlen(data)), ROUTER_IP);

我遇到的问题是接收端只是获取随机数据,所以我假设某处的字节数不正确。

在接收端,我让它打印出 IP 标头的一个字段作为测试,但它不正确。

char recv_buff[1000];
int recv_bytes = recvfrom(sock, recv_buff, sizeof(recv_buff));
struct iphdr *ip = (struct iphdr*) recv_buff;
cout << static_cast<int16_t>(ip->ttl) << endl;

我将数据包放在一起是错误的还是接收端有问题?我使用这个示例http://www.winlab.rutgers.edu/~zhibinwu/html/c_prog.htm作为将数据包放在一起的参考。

4

3 回答 3

2

您正在创建套接字,socket(AF_INET, SOCK_DGRAM, 0);这意味着它是一个数据报(通常为 UDP)套接字,因此网络堆栈将自动包含 IP 标头和 UDP 标头等。

但是由于您尝试创建自己的 IP 和 UDP 标头,因此您必须创建一个原始套接字,然后发送数据包(并按照您的参考代码计算校验和)。

要创建原始套接字,请使用socket(AF_INET, SOCK_RAW, 0).

于 2012-11-29T05:52:13.547 回答
1

除了不使用原始套接字的问题外,您也没有正确设置例如端口号。必须是网络字节顺序,所以你应该使用例如htons。还有其他字段应该按网络字节顺序排列。

于 2012-11-29T08:01:33.363 回答
0

如果您在堆栈顶部使用自己的 ip 和 udp 标头,我希望您在删除您的标头和堆栈的标头后解析数据。如果接收套接字是 RAW,您还将获得堆栈的 ip 和 udp 标头。

于 2012-11-30T07:05:31.813 回答