C ++ - 构建带有标头的数据包并通过UDP套接字发送它

时间:2012-11-29 05:26:12

标签: c++ c sockets networking

我正在尝试构建一个将通过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作为汇总数据包的参考。

3 个答案:

答案 0 :(得分:2)

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

但是,既然您正在尝试创建自己的IP和UDP标头,则必须创建一个原始套接字,然后发送数据包(并且还会像参考代码那样计算校验和)。

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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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