我正在尝试创建一个应用程序,它可以使用DatagramSockets和DatagramPackets以块的形式发送文件(我必须这样做)。 数据包使用其他信息(片段数,片段索引等)编码。我面临的问题是:
我有一个CustomThread正在运行,等待数据包到达,然后通过MainNotifier对象通知控制器它到达,它在实例化过程中被传递给CustomThread。然后MainNotifier处理它。控制器是创建和启动线程的对象。现在我的假设是MainNotifier中的处理函数仍然在CustomThread上运行,因为它调用它们,这可能导致一个状态,即由于前一个数据包正在被处理而没有捕获到达数据包。这是一个正确的假设还是完全错误的?如果是这样我怎么能绕过它呢?创建一个单独的线程来处理控制器/ MainNotifier中的传入包会减轻CustomThread的处理负担吗?
public void run(){
while (open){
byte[] buff = new byte[1472];
DatagramPacket packet = new DatagramPacket(buff, buff.length);
try {
socket.receive(packet);
mainNotifier.notifyReceivedMessage(packet);
} catch (IOException e) {
e.printStackTrace();
}
}
socket.close();
}
我发布了这么一小段代码,因为我相信我的假设是正确的,并且数据包的处理功能在这种情况下并不是非常重要。
答案 0 :(得分:3)
是的,数据填充低级缓冲区的速度可能比消耗和删除的速度快。将数据传递到队列以供另一个线程处理可以解决您当前的问题。
但是,这不是UDP traffic can be lost唯一的方式。
您的协议与TFTP有一些相似之处,因为文件是通过UDP传输的。您可能希望查看该协议以获得有关重新传输的灵感。
我不是建议您实施TFTP。它跳转端口和服务器成为客户端的方式并不好。
答案 1 :(得分:3)
并非所有包含文件片段的数据包都被另一个接收 侧
这是UDP的设计特性。您不能指望收到所有数据包,因此您需要在监控数据包传输或允许数据包丢失的代码中实施策略。
由于你有一个文件(并且缺少它听起来不是一件好事)我相信你需要监控哪些数据包已被接收。你如何做到这一点取决于你想要的结果;但是,如果您使用TCP,它会为您处理重新传输。
如果您试图通过转移到UDP来击败TCP的性能,请记住,使用TCP获得较低性能的部分原因是因为TCP会为您跟踪并重新传送丢失的数据包。