我正在实现2个使用滑动窗口协议作为数据链路协议和UDP套接字进行通信的应用程序。我正在尝试使用Tanembaum的书作为参考来实现滑动窗口协议。这是我在书中找到的代码。
/* Protocol 4 (sliding window) is bidirectional and is more robust than protocol 3. */
#define MAX_SEQ 1 /* must be 1 for protocol 4 */
typedef enum {frame_arrival, cksum_err, timeout} event_type;
#include "protocol.h"
void protocol4 (void)
{
seq_nr next_frame_to_send; /* 0 or 1 only */
seq_nr frame_expected; /* 0 or 1 only */
frame r, s; /* scratch variables */
packet buffer; /* current packet being sent */
event_type event;
next_frame_to_send = 0; /* next frame on the outbound stream */
frame_expected = 0; /* number of frame arriving frame expected */
from_network_layer(&buffer); /* fetch a packet from the network layer */
s.info = buffer; /* prepare to send the initial frame */
s.seq = next_frame_to_send; /* insert sequence number into frame */
s.ack = 1 - frame_expected; /* piggybacked ack */
to_physical_layer(&s); /* transmit the frame */
start_timer(s.seq); /* start the timer running */
while (true) {
wait_for_event(&event); /* could be: frame_arrival, cksum_err, timeout */
if (event == frame_arrival) { /* a frame has arrived undamaged. */
from_physical_layer(&r); /* go get it */
if (r.seq == frame_expected) {
/* Handle inbound frame stream. */
to_network_layer(&r.info); /* pass packet to network layer */
inc(frame_expected); /* invert sequence number expected next */
}
if (r.ack == next_frame_to_send) { /* handle outbound frame stream. */
from_network_layer(&buffer); /* fetch new packet from network layer */
inc(next_frame_to_send); /* invert sender's sequence number */
}
}
s.info = buffer; /* construct outbound frame */
s.seq = next_frame_to_send; /* insert sequence number into it */
s.ack = 1 - frame_expected; /* seq number of last received frame */
to_physical_layer(&s); /* transmit a frame */
start_timer(s.seq); /* start the timer running */
}
}
我把它翻译成java有点困惑。我不确切知道如何在这里应用线程。我正在寻找任何可以帮助我实现这一目标的提示和策略。
修改
我最困惑的是:
答案 0 :(得分:1)
首先:在将时间和精力投入到UDP顶部的滑动窗口层之前,检查您是否需要这种奇特的解决方案。 TCP已经做了那样的事情,许多人投入了大量时间来使其正确和健壮。但实施这种解决方案当然有正当理由。下一步应该是谷歌周围,很可能已经有几十个非常相似的程序。特别是因为你似乎没有很多Java网络API的经验,从一段工作的Java代码开始,而不是从一本更适合学习人们网络概念的书中的例子来看,效率可能要高得多。 / p>
无论如何,如果你想通过阅读DatagramSocket类的Javadoc来重新实现上面的协议。它有一个setSoTimeout方法可以替换上面代码中的计时器,主要的区别是超时receive会抛出一个SocketTimeoutException,这可能会使程序的流程变得复杂一些。忘记from_physical和to_physical位,所有这些东西都被Socket类包装。
答案 1 :(得分:1)
实现函数wait_for_event()和start_timer()。
你不需要它们。分别使用DatagramSocket.setSoTimeout()
和catch (SocketTimeoutException)
。
我应该把UDP套接字放在哪里?我认为UDP套接字部分位于to_physical_layer()和from_physical_layer()中。如果我错了,请纠正。
与当前recv()
和send()
来电相同。
由于协议是双向的,两个应用程序都应该具有相同的代码吗?
是