-3

我正在实现 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有点困惑。我不知道线程是如何在这里应用的。我正在寻找任何可以帮助我实现这一点的提示和策略。

编辑

我最困惑:

  • 在实现函数 wait_for_event() 和 start_timer() 时。
  • 我应该把 UDP 套接字部分放在哪里?我认为 UDP 套接字部分在 to_physical_layer() 和 from_physical_layer() 内。如果我错了,请纠正。
  • 由于协议是双向的,两个应用程序是否应该具有相同的代码?
4

2 回答 2

1

在实现函数 wait_for_event() 和 start_timer() 时。

你不需要它们。分别使用DatagramSocket.setSoTimeout()catch (SocketTimeoutException)

我应该把 UDP 套接字部分放在哪里?我认为 UDP 套接字部分在 to_physical_layer() 和 from_physical_layer() 内。如果我错了,请纠正。

recv()与现在和send()电话相同的地方。

由于协议是双向的,两个应用程序是否应该具有相同的代码?

是的。

于 2013-02-03T03:47:02.073 回答
1

首先:在将时间和精力投入到 UDP 之上的滑动窗口层之前,请检查您是否需要这种奇特的解决方案。TCP 已经在做这种事情,许多人已经投入了大量时间来使其正确和强大。但是当然有充分的理由来实施这样的解决方案。下一步应该是谷歌,可能已经有几十个非常相似的程序了。尤其是因为您似乎对 Java 的网络 API 没有太多经验,所以从一段 Java 代码开始可能比从一本更适合学习人际网络概念的书中的示例开始更有效率。

无论如何,如果你想重新实现上面的协议,首先阅读DatagramSocket类的 Javadoc。它有一个setSoTimeout方法,可以替换上面代码中的计时器,主要区别在于接收超时时 会抛出 SocketTimeoutException,这可能会使您的程序流程稍微复杂化。忘记 from_physical 和 to_physical 位,所有这些东西都由 Socket 类包装。

于 2013-02-03T00:20:30.197 回答