停止并等待文件传输协议,何时停止收听?

时间:2012-03-05 23:01:18

标签: c++ sockets ftp udp file-transfer

我正在使用UDP上的C ++套接字(SOCK_DGRAM)开发客户端和服务器文件传输应用程序。对于PUT方法,我有以下执行(握手后):

client

Send a packet;
if time_out
    send the packet again;
else  //ack received
    send a new packet;

server

wait for the first packet;
send acknowledge;
while(!EOF)
    Get a packet;
    Send an ack;

EOF基本上是通过比较握手期间发送的文件大小来检查我是否收到了整个文件。

在此次交换期间,任何时候都可能丢失数据包。客户端可以发送丢失的数据包。它会超时等待ACK并重新发送数据包。服务器接收数据包并发送ACK。该ACK可能会丢失,此时客户端超时并重新发送其数据包。由于这些数据包具有编号序列,我们可以忽略我们多次收到的数据包。

我的混淆发生在文件传输结束时。客户端刚刚发送了包含文件最后几位的数据包。服务器成功接收并发送其ACK。这个数据包丢失了。服务器应用程序现在位于while循环之外,因为他已将最后一位写入文件,从他的角度来看,文件传输成功。但是,客户端从未收到ACK,因此超时并重新发送数据包。这会发生什么?服务器没有正在侦听或正在侦听新请求,而不是数据。客户端或服务器应该在何时考虑完成传输并停止尝试通信?

2 个答案:

答案 0 :(得分:2)

听起来你正在重新发明TFTP,但客户端和服务器角色倒退了。你确定需要这样做吗?由于缺少滑动窗口或数据管道,这是一个非常低效的协议。

我认为你的难题有3个解决方案:

  • 文件传输结束时的三次握手。在接收到最后一个数据块之后,服务器不仅发送ACK,而且等待客户端确认ACK。发生这种情况时,服务器知道客户端知道文件传输已完成。如果服务器从未收到ACK的ACK,它会定期重新发送其最后一个数据块的ACK。
  • 服务器在完成后会记住几分钟完成的文件传输(或几个RTT,以较大者为准)。如果在此期间,它从客户端接收到应该已经完成​​的文件传输的任何数据块,则服务器只是确认它而不做任何事情并重置该文件传输的传输结束计时器。这比以前的解决方案更复杂,但是在文件传输完成后,服务器能够继续前进并完成其他工作。
  • 如果服务器收到任何不属于活动文件传输的数据块,则会响应错误(NAK)。这是否是不存在,无效或已完成转移的一部分。这是最简单的实现,但也是最丑陋的,因为客户端在收到NAK时必须以错误终止。但也许没关系,因为从服务器的角度来看,文件传输仍然是成功的。

答案 1 :(得分:1)

显而易见的解决方案是阻止服务器立即监听。我会让服务器不断发送一个特殊的数据包,其值代表end of file,直到从客户端收到确认为止。

您是否考虑过使用已经实现此类UDP文件传输的库,例如Raknet?它可能会让你的生活变得更轻松,因为你在这里重新发明轮子。

相关问题