我正在使用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,因此超时并重新发送数据包。这会发生什么?服务器没有正在侦听或正在侦听新请求,而不是数据。客户端或服务器应该在何时考虑完成传输并停止尝试通信?
答案 0 :(得分:2)
听起来你正在重新发明TFTP,但客户端和服务器角色倒退了。你确定需要这样做吗?由于缺少滑动窗口或数据管道,这是一个非常低效的协议。
我认为你的难题有3个解决方案:
答案 1 :(得分:1)
显而易见的解决方案是不阻止服务器立即监听。我会让服务器不断发送一个特殊的数据包,其值代表end of file
,直到从客户端收到确认为止。
您是否考虑过使用已经实现此类UDP文件传输的库,例如Raknet?它可能会让你的生活变得更轻松,因为你在这里重新发明轮子。