现在的位置: 首页 > 综合 > 正文

《计算机网络》读书笔记(三)

2012年05月22日 ⁄ 综合 ⁄ 共 14055字 ⁄ 字号 评论关闭

《计算机网络》读书笔记(三)
数据链路层
        数据链路层需要完成的功能包括三个方面:1.向网络层提供一个定义良好的服务接口;2.处理传输错误;3.调节数据流,确保接受方不会被淹没。
        数据链路层提供三种服务:1.无确认的无连接的服务(绝大多数LAN使用);2.有确认的无连接的服务(比如无线系统);3.有确认的面向连接的服务。
       数据链路层的几种成帧方法:1.字符记数法;2.含字节填充的分界符法;3.含位填充的分界标志法;4.物理层编码违例法。
        流控制包括两种:1.基于反馈的流控制(数据链路层使用);2.基于速率的流控制。
        错误检测和纠正:1.纠错码,也叫做向前纠错;2.检错码。海明距离:为了检测d个错误,需要一个距离为d+1的编码方案;为了纠正d个错误,需要一个距离为2d+1的编码方案。    CRC(Cyclic Redundancy Check,循环冗余校检码)。。。。。。。更多等带以后添加基本数据链路协议,参照后面的1.c,是一个支持重传的肯定确认协议。
        滑动窗口协议:所有滑动窗口协议的本质是,在任何时刻,发送方总是维持着一组序列号,分别对应准许它发送的帧,我们称这些帧在发送窗口之内,类似的,接收方也维护着一个接受窗口。三个例子:1.1位滑动窗口协议;2.使用回退N帧技术的协议;3.使用选择性重传的协议。详细参照后面的三个C程序。
        协议验证:1.有限状态机模型:许多协议模型中用到的一个关键概念是有限状态机(finite state machine),每个协议机(即发送方或接受方)在任何一个时刻,总是处于一种特定的状态,它的状态是由所有变量的值组成的,其中也包括程序计数器;2.Petri网模型:一个Petri网有4个基本元素:库所(place),变迁(transition),弧(arc)和标记(token)。
        HDLC(High-level Data Link Control,高级数据链路控制):所有协议都是面向位的,并且为了确保数据的透明性,它们都使用了位填充。
        PPP(Point-to-Point Protocol,点到点协议):Internet中大量使用该协议,PPP提供了三类功能:1.一种支持错误检测的成帧方法;2.一个LCP链路控制协议,支持同步和异步线路,也支持面向字节的和面向位的编码方法;3.一种协商网络层选项的方法,并且协商方法与所使用的网络层协议独立,所选择的方法对于每一种支持的网络层都有一个不同的NCP(网络控制协议)。

//protocol.h
#define MAX_PKT 1024 /* determines packet size in bytes */

typedef enum {false, true} boolean; /* boolean type */
typedef unsigned int seq_nr; /* sequence or ack numbers */
typedef struct {unsigned char data[MAX_PKT];} packet; /*    packet definition */
typedef enum {data, ack, nak} frame_kind; /* frame_kind definition */

typedef struct { /* frames are transported in this layer */
  frame_kind kind; /* what kind of a frame is it? */
  seq_nr seq;    /* sequence number */
  seq_nr ack;    /* acknowledgement number */
  packet info;   /* the network layer packet */
} frame;

/* Wait for an event to happen; return its type in event. */
void wait_for_event(event_type *event);

/* Fetch a packet from the network layer for transmission on the channel. */
void from_network_layer(packet *p);

/* Deliver information from an inbound frame to the network layer. */
void to_network_layer(packet *p);

/* Go get an inbound frame from the physical layer and copy it to r. */
void from_physical_layer(frame *r);

/* Pass the frame to the physical layer for transmission. */
void to_physical_layer(frame *s);

/* Start the clock running and enable the timeout event. */
void start_timer(seq_nr k);

/* Stop the clock and disable the timeout event. */
void stop_timer(seq_nr k);

/* Start an auxiliary timer and enable the ack_timeout event. */
void start_ack_timer(void);

/* Stop the auxiliary timer and disable the ack_timeout event. */
void stop_ack_timer(void);

/* Allow the network layer to cause a network_layer_ready event. */
void enable_network_layer(void);

/* Forbid the network layer from causing a network_layer_ready event. */
void disable_network_layer(void);

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

//1.c
#define MAX_SEQ 1  /* must be 1 for protocol 3 */
typedef enum  {frame_arrival, cksum_err, timeout} event_type;
#include "protocol.h"
void sender3(void)
{
  seq_nr next_frame_to_send;   /* seq number of next outgoing frame */
  frame s;     /* scratch variable */
  packet buffer;    /* buffer for an outbound packet */
  event_type event;
  next_frame_to_send = 0;   /* initialize outbound sequence numbers */
  from_network_layer(&buffer);   /* fetch first packet */
  while (true) {
        s.info = buffer;   /* construct a frame for transmission */
        s.seq = next_frame_to_send;  /* insert sequence number in frame */
        to_physical_layer(&s);   /* send it on its way */
        start_timer(s.seq);   /* if answer takes too long, time out */
        wait_for_event(&event);   /* frame_arrival, cksum_err, timeout */
        if (event == frame_arrival) {
                from_physical_layer(&s);      /* get the acknowledgement */
                if (s.ack == next_frame_to_send) {
                        stop_timer(s.ack);      /* turn the timer off */
                        from_network_layer(&buffer); /* get the next one to send */
                        inc(next_frame_to_send);     /* invert next_frame_to_send */
                }
        }
  }
}

void receiver3(void)
{
  seq_nr frame_expected;
  frame r, s;
  event_type event;
  frame_expected = 0;
  while (true) {
        wait_for_event(&event);   /* possibilities: frame_arrival, cksum_err */
        if (event == frame_arrival) {  /* a valid frame has arrived. */
                from_physical_layer(&r); /* go get the newly arrived frame */
                if (r.seq == frame_expected) { /* this is what we have been waiting for. */
                        to_network_layer(&r.info); /* pass the data to the network layer */
                        inc(frame_expected); /* next time expect the other sequence nr */
                }
                s.ack = 1 - frame_expected; /* tell which frame is being acked */
                to_physical_layer(&s);  /* send acknowledgement */
        }
  }
}

#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;  /* frame expected next */
  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); /* frame_arrival, cksum_err, or 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 seq number expected next */
                }
                if (r.ack == next_frame_to_send) {  /* handle outbound frame stream. */
                        stop_timer(r.ack);     /* turn the timer off */
                        from_network_layer(&buffer);/* fetch new pkt 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 */
  }
}

#define MAX_SEQ 7  /* should be 2^n - 1 */
typedef enum {frame_arrival, cksum_err, timeout, network_layer_ready} event_type;
#include "protocol.h"

static boolean between(seq_nr a, seq_nr b, seq_nr c)
{
/* Return true if a <=b < c circularly; false otherwise. */
  if (((a <= b) && (b < c)) || ((c < a) && (a <= b)) || ((b < c) && (c < a)))
        return(true);
    else
        return(false);
}

static void send_data(seq_nr frame_nr, seq_nr frame_expected, packet buffer[])
{
/* Construct and send a data frame. */
  frame s;   /* scratch variable */

  s.info = buffer[frame_nr]; /* insert packet into frame */
  s.seq = frame_nr;  /* insert sequence number into frame */
  s.ack = (frame_expected + MAX_SEQ) % (MAX_SEQ + 1); /* piggyback ack */
  to_physical_layer(&s); /* transmit the frame */
  start_timer(frame_nr); /* start the timer running */
}

void protocol5(void)
{
  seq_nr next_frame_to_send; /* MAX_SEQ > 1; used for outbound stream */
  seq_nr ack_expected;  /* oldest frame as yet unacknowledged */
  seq_nr frame_expected; /* next frame expected on inbound stream */
  frame r;   /* scratch variable */
  packet buffer[MAX_SEQ + 1]; /* buffers for the outbound stream */
  seq_nr nbuffered;  /* # output buffers currently in use */
  seq_nr i;   /* used to index into the buffer array */
  event_type event;

  enable_network_layer(); /* allow network_layer_ready events */
  ack_expected = 0;  /* next ack expected inbound */
  next_frame_to_send = 0; /* next frame going out */
  frame_expected = 0;  /* number of frame expected inbound */
  nbuffered = 0;  /* initially no packets are buffered */
  while (true) {
     wait_for_event(&event); /* four possibilities: see event_type above */

     switch(event) {
        case network_layer_ready:  /* the network layer has a packet to send */
                /* Accept, save, and transmit a new frame. */
                from_network_layer(&buffer[next_frame_to_send]); /* fetch new packet */
                nbuffered = nbuffered + 1; /* expand the sender's window */
                send_data(next_frame_to_send, frame_expected, buffer); /* transmit the frame */
                inc(next_frame_to_send); /* advance sender's upper window edge */
                break;
 
        case frame_arrival:   /* a data or control frame has arrived */
                from_physical_layer(&r); /* get incoming frame from physical layer */
 
                if (r.seq == frame_expected) {
                        /* Frames are accepted only in order. */
                        to_network_layer(&r.info); /* pass packet to network layer */
                        inc(frame_expected); /* advance lower edge of receiver's window */
                 }
 
                 /* Ack n implies n - 1, n - 2, etc.  Check for this. */
                while (between(ack_expected, r.ack, next_frame_to_send)) {
                        /* Handle piggybacked ack. */
                        nbuffered = nbuffered - 1; /* one frame fewer buffered */
                        stop_timer(ack_expected);  /* frame arrived intact; stop timer */
                        inc(ack_expected);    /* contract sender's window */
                }
                break;

        case cksum_err: break;      /* just ignore bad frames */
 
        case timeout: /* trouble; retransmit all outstanding frames */
                next_frame_to_send = ack_expected; /* start retransmitting here */
                for (i = 1; i <= nbuffered; i++) {
                        send_data(next_frame_to_send, frame_expected, buffer); /* resend 1 frame */
                        inc(next_frame_to_send);   /* prepare to send the next one */
                }

     }
 
     if (nbuffered < MAX_SEQ)
                enable_network_layer();
     else
                disable_network_layer();
  }
}

#define MAX_SEQ 7  /* should be 2^n - 1 */
#define NR_BUFS ((MAX_SEQ + 1)/2)
typedef enum {frame_arrival, cksum_err, timeout, network_layer_ready, ack_timeout} event_type;
#include "protocol.h"
boolean no_nak = true;  /* no nak has been sent yet */
seq_nr oldest_frame = MAX_SEQ + 1; /* initial value is only for the simulator */
static boolean between(seq_nr a, seq_nr b, seq_nr c)
{
/* Same as between in protocol5, but shorter and more obscure. */
  return ((a <= b) && (b < c)) || ((c < a) && (a <= b)) || ((b < c) && (c < a));
}
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 */
}
void protocol6(void)
{
  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 */
  event_type event;

  enable_network_layer(); /* initialize */
  ack_expected = 0;  /* next ack expected on the inbound stream */
  next_frame_to_send = 0; /* number of next outgoing frame */
  frame_expected = 0;
  too_far = NR_BUFS;
  nbuffered = 0;  /* initially no packets are buffered */
  for (i = 0; i < NR_BUFS; i++) arrived[i] = false;
  while (true) {
     wait_for_event(&event); /* five possibilities: see event_type above */
     switch(event) {
        case network_layer_ready: /* accept, save, and transmit a new frame */
                nbuffered = nbuffered + 1; /* expand the window */
                from_network_layer(&out_buf[next_frame_to_send % NR_BUFS]); /* fetch new packet */
                send_frame(data, next_frame_to_send, frame_expected, out_buf); /* transmit the frame */
                inc(next_frame_to_send); /* advance upper window edge */
                break;

        case frame_arrival:  /* a data or control frame has arrived */
                from_physical_layer(&r);/* fetch incoming frame from physical layer */
                if (r.kind == data) {
                        /* An undamaged frame has arrived. */
                        if ((r.seq != frame_expected) && no_nak)
                            send_frame(nak, 0, frame_expected, out_buf); else start_ack_timer();
                        if (between(frame_expected, r.seq, too_far) && (arrived[r.seq%NR_BUFS] == false)) {
                                /* Frames may be accepted in any order. */
                                arrived[r.seq % NR_BUFS] = true; /* mark buffer as full */
                                in_buf[r.seq % NR_BUFS] = r.info; /* insert data into buffer */
                                while (arrived[frame_expected % NR_BUFS]) {
                                        /* Pass frames and advance window. */
                                        to_network_layer(&in_buf[frame_expected % NR_BUFS]);
                                        no_nak = true;
                                        arrived[frame_expected % NR_BUFS] = false;
                                        inc(frame_expected); /* advance lower edge of receiver's window */
                                        inc(too_far);  /* advance upper edge of receiver's window */
                                        start_ack_timer(); /* to see if a separate ack is needed */
                                }
                        }
                }
                if((r.kind==nak) && between(ack_expected,(r.ack+1)%(MAX_SEQ+1),next_frame_to_send))
                        send_frame(data, (r.ack+1) % (MAX_SEQ + 1), frame_expected, out_buf);

                while (between(ack_expected, r.ack, next_frame_to_send)) {
                        nbuffered = nbuffered - 1; /* handle piggybacked ack */
                        stop_timer(ack_expected % NR_BUFS); /* frame arrived intact */
                        inc(ack_expected); /* advance lower edge of sender's window */
                }
                break;

        case cksum_err:
                if (no_nak) send_frame(nak, 0, frame_expected, out_buf); /* damaged frame */
                break;

        case timeout:
                send_frame(data, oldest_frame, frame_expected, out_buf);  /* we timed out */
                break;

        case ack_timeout:
                send_frame(ack,0,frame_expected, out_buf); /* ack timer expired; send ack */
     }
     if (nbuffered < NR_BUFS) enable_network_layer(); else disable_network_layer();
  }
}

抱歉!评论已关闭.