⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 datalink.c

📁 数据链路层滑动窗口协议的设计与实现。有完整的说明和模拟环境文档。
💻 C
字号:
#define MAX_SEQ 7	/* should be 2^n - 1 */
#define NR_BUFS ((MAX_SEQ + 1)/2)

#include <stdio.h>
#include "protocol.h"


static int phl_ready = 0;
boolean no_nak = true;	/* no nak has been sent yet */
seq_nr oldest_frame = MAX_SEQ+1;	/* init value is for the simulator */

/* Macro inc is expanded in-line: Increment k circularly. */
#define inc(k) if (k < MAX_SEQ) k = k + 1; else k = 0

static void send_frame(frame_kind fk, seq_nr frame_nr, seq_nr frame_expected, packet buffer[])
{
/* Construct and send a data, ack, or nak frame. */
    frame s;	/* scratch variable */

    s.kind = fk;	/* kind == data, ack, or nak */
    if (fk == data) s.info = buffer[frame_nr % NR_BUFS];
    s.seq = frame_nr;	/* only meaningful for data frames */
    s.ack = (frame_expected + MAX_SEQ) % (MAX_SEQ + 1);
    if (fk == nak) no_nak = false;	/* one nak per frame, please */
    to_physical_layer(&s);	/* transmit the frame */
    if (fk == data) start_timer(frame_nr % NR_BUFS);
    stop_ack_timer();	/* no need for separate ack frame */
}

int main(int argc, char **argv)
{
    int event, arg, i, len = 0;
    unsigned char ch, my_buf[256];

	seq_nr ack_expected;	/* lower edge of sender's window */
    seq_nr next_frame_to_send;	/* upper edge of sender's window + 1 */
    seq_nr frame_expected;	/* lower edge of receiver's window */
    seq_nr too_far;	/* upper edge of receiver's window + 1 */
    int i;	/* index into buffer pool */
    frame r;	/* scratch variable */
    packet out_buf[NR_BUFS];	/* buffers for the outbound stream */
    packet in_buf[NR_BUFS];	/* buffers for the inbound stream */
    boolean arrived[NR_BUFS];	/* inbound bit map */
    seq_nr nbuffered;	/* how many output buffers currently used */

    protocol_init(argc, argv); 
    enable_network_layer();

	ack_expected = 0;	/* next ack expected on the inbound stream */
    next_frame_to_send = 0;	/* number of next outgoing frame */
    frame_expected = 0;	/* frame number expected */
    too_far = NR_BUFS;	/* receiver's upper window + 1 */
    nbuffered = 0;	/* initially no packets are buffered */

    for (;;) {
        event = wait_for_event(&arg);

        switch (event) {
        case NETWORK_LAYER_READY:
			nbuffered = nbuffered + 1;	/* expand the window */
            len = get_packet(out_buf[next_frame_to_send % NR_BUFS])+7; 
            if (phl_ready) {
                log_printf("L3: Send %d bytes\n", len);
                send_frame(data, next_frame_to_send, frame_expected, out_buf);	/* transmit the frame */
                inc(next_frame_to_send);	/* advance upper window edge */
				phl_ready  = 0;
                len = 0;
            }
            break;

        case PHYSICAL_LAYER_READY:
            if (len) {
                log_printf("Send %d bytes\n", len);
                send_frame(data, next_frame_to_send, frame_expected, out_buf);	/* transmit the frame */
                inc(next_frame_to_send);	/* advance upper window edge */
                phl_ready = 0;
                len = 0;
            } else
                phl_ready = 1;

            break;

        case DATA_INCOMING: 
            log_printf("Rcvd %d bytes : ", arg);
            for (i = 0; i < arg; i++) {
                ch = recv_byte();
                lprintf("%02x ", ch); fflush(stdout);
                /* 
                    ... ...
                */
            }
            lprintf("\n");
            break; 

        case ACK_TIMEOUT:
            /* 
                ... ...
            */
            break;

        case DATA_TIMEOUT:
            /* 
                ... ...
            */
            break;
        }

        /*
        if (nbuffered < MAX_SEQ)
            enable_network_layer();
        else
            disable_network_layer();
        */
        if (len == 0)
            enable_network_layer();
        else
            disable_network_layer();

    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -