我正在开发一个使用 UDP 的可靠文件传输程序。(计算机网络课程。)
我的问题是 - 好吧,考虑一下这种情况:
发送者(例如)有 12 个字节的数据要发送。所以发送者执行这个调用:
sendto(fd, &buf, 12, 0, (struct sockaddr *)&cliaddr,sizeof(cliaddr));
这会以不可靠的方式发送 12 个字节的数据。该数据的前 4 个字节恰好是“消息长度”字段。在这种情况下,前 4 个字节的值可能为 0x0000000C
接收方想要使用 recvfrom() 读取前 4 个字节。看到段大小是 12 字节,它想读取剩余的 8 字节。所以接收器可能看起来像这样:
/* read the segment size */ recvfrom(sockfd,&buf,4,0,(struct sockaddr *)&cliaddr,&len); /* do some arithmetic, use bzero(), etc */ /* read the rest of the data */ recvfrom(sockfd,&buf,8,0,(struct sockaddr *)&cliaddr,&len);
当我执行此代码时,我可以毫无问题地接收前 4 个字节。但是当我尝试获取剩余的数据时,这些数据似乎丢失了。在我的输出中,我得到了垃圾 - 它看起来像是发送者正在发送到()的下一个12 个字节的一部分。
这是预期的行为吗?也就是说,如果单个recvfrom()调用没有读取所有发送的数据,是不是不能保证数据(剩余的8个字节)可供我使用?
似乎发送段标头(包括其大小)和有效负载的标准方法不起作用。这是否意味着我需要发送 2 个单独的段 - 一个仅包含标头信息,然后是带有有效负载的第二个段?还是我只是错误地使用了这些系统调用(或者是否有我缺少的标志或 setsockopt()?)