2013-02-02 168 views
-3

我正在實現2個使用滑動窗口協議作爲數據鏈接協議和UDP套接字進行通信的應用程序。我試圖使用Tanembaum的書作爲參考來實現滑動窗口協議。這是我在書中找到的代碼。如何將此代碼移植到Java?

/* 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()之內。如果我錯了,請糾正。
  • 由於協議是雙向的,兩個應用程序應該具有相同的代碼嗎?
+1

這是簡單的非線程C代碼,可以在Java中保持這種方式。同時請解釋一下你在翻譯成Java時遇到的困惑。 – fvu

+0

這裏的片段幾乎是1-1移植到java。樣本中沒有涉及任何線程。 – bestsss

+0

編輯了這個問題 –

回答

1
在執行功能wait_for_event()和START_TIMER

()。

你不需要他們。分別使用DatagramSocket.setSoTimeout()catch (SocketTimeoutException)

我應該在哪裏把UDP套接字的一部分?我認爲UDP套接字部分位於to_physical_layer()和from_physical_layer()之內。如果我錯了,請糾正。

與現在的recv()send()調用相同的地方。

都應該應用具有相同的代碼,因爲該協議是雙向的?

是的。

1

首先:在將時間和精力投入到UDP頂層的滑動窗口層之前,檢查是否需要這樣一個奇特的解決方案。 TCP已經做了這樣的事情,許多人花費了大量的時間來使它正確和健壯。但是,實施這樣的解決方案當然有正當的理由。下一步應該是谷歌周圍,有可能已經有幾十個非常類似的計劃。特別是因爲你似乎對Java的網絡API沒有太多的經驗,所以從一段Java代碼開始,比從一本更適合學習人們網絡概念的書籍的例子,開始更有效率。

不管怎麼說,如果你想通過閱讀對DatagramSocket類的Javadoc重新實現上面開始的協議。它有一個setSoTimeout方法,可以替換上面的代碼中的計時器事件,主要區別在於,在超時時receive將引發SocketTimeoutException,並且可能會使程序的流程稍微複雜一些。忘記from_physical和to_physical位,所有的東西都被Socket類包裝了。