Desol 2018-04-16 03:20 采纳率: 50%
浏览 1032
已结题

计算机网络构建传输协议相关问题

通过c写了一个交换比特协议,part2 要求添加流水线化的窗口,需要窗口大小为6的go back n协议。有点摸不着头脑,请大神指点。以下是代码:
#include
#include
#include
#include "emulator.h"
#include "altbit.h"

/* ******************************************************************
Unfinished Alternating bit protocol. Adapted from
ALTERNATING BIT AND GO-BACK-N NETWORK EMULATOR: VERSION 1.1 J.F.Kurose

Network properties:

  • one way network delay averages five time units (longer if there are other messages in the channel for GBN), but can be larger
  • packets can be corrupted (either the header or the data portion) or lost, according to user-defined probabilities
  • packets will be delivered in the order in which they were sent
    (although some can be lost).

    Modifications (6/6/2008 - CLP):

  • removed bidirectional code and other code not used by prac.

  • fixed C style to adhere to current programming style
    (7/8/2009 - CLP)

  • converted to Alt Bit
    **********************************************************************/

#define RTT 15.0 /* round trip time. MUST BE SET TO 15.0 when submitting assignment /
#define WINDOWSIZE 1 /
alternating bit only allows one unacked packet /
#define NOTINUSE (-1) /
used to fill header fields that are not being used */

/* generic procedure to compute the checksum of a packet. Used by both sender and receiver

the simulator will overwrite part of your packet with 'z's. It will not overwrite your
original checksum. This procedure must generate a different checksum to the original if
the packet is corrupted.
*/
int ComputeChecksum(struct pkt packet)
{
int checksum = 0;
int i;

/****** 4. FILL IN CODE to calculate the checksum of packet *****/
checksum = packet.seqnum + packet.acknum;
for(i = 0;i < 20 ;i++)
{
checksum = checksum + packet.payload[i];
}

return checksum;
}

bool IsCorrupted(struct pkt packet)
{
if (packet.checksum == ComputeChecksum(packet))
return (false);
else
return (true);
}

/********* Sender (A) variables and functions ************/

static struct pkt buffer[WINDOWSIZE]; /* array for storing packets waiting for ACK /
static int windowfirst, windowlast; /
array indexes of the first/last packet awaiting ACK /
static int windowcount; /
the number of packets currently awaiting an ACK /
static int A_nextseqnum; /
the next sequence number to be used by the sender */

/* called from layer 5 (application layer), passed the message to be sent to other side */
void A_output(struct msg message)
{
struct pkt sendpkt;
int i;

/* if not blocked waiting on ACK */
if ( windowcount < WINDOWSIZE) {
if (TRACE > 1)
printf("----A: New message arrives, send window is not full, send new messge to layer3!\n");

/* create packet */
sendpkt.seqnum = A_nextseqnum;
sendpkt.acknum = NOTINUSE;
for ( i=0; i<20 ; i++ ) 
  sendpkt.payload[i] = message.data[i];
sendpkt.checksum = ComputeChecksum(sendpkt); 

/* put packet in window buffer */
/* windowlast will always be 0 for alternating bit; but not for GoBackN */
windowlast = (windowlast + 1) % WINDOWSIZE; 
buffer[windowlast] = sendpkt;
for (i=0; i<20; i++)
  buffer[windowlast].payload[i]=sendpkt.payload[i];  /* copy the array */
windowcount++;

/* send out packet */
if (TRACE > 0)
  printf("Sending packet %d to layer 3\n", sendpkt.seqnum);
tolayer3 (A, sendpkt);
/**** 1. FILL IN CODE There's something else A needs to do when it sends a packet. *****/
starttimer(A,15.0);

A_nextseqnum = (A_nextseqnum + 1) % 2;  /* we only have seqnum 0 and 1 */

}
/* if blocked, window is full */
else {
if (TRACE > 0)
printf("----A: New message arrives, send window is full\n");
window_full++;
}
}

/* called from layer 3, when a packet arrives for layer 4
In this practical this will always be an ACK as B never sends data.
*/
void A_input(struct pkt packet)
{
int veriack;
veriack = new_ACKs%2;

/* if received ACK is not corrupted /
if (!IsCorrupted(packet)) {
if (TRACE > 0)
printf("----A: uncorrupted ACK %d is received\n",packet.acknum);
total_ACKs_received++;
/
check if new ACK or duplicate /
if (packet.acknum == veriack) { /
*** 2. FILL IN CODE replace TRUE with test whether this is a new ACK ***/
/* packet is a new ACK */
if (TRACE > 0)
printf("----A: ACK %d is not a duplicate\n",packet.acknum);
new_ACKs++;

  /* delete the acked packets from window buffer */
  windowcount--;

  /***** 1. FILL IN CODE  What else needs to be done when an ACK arrives
   besides removing the packet from the window?  ****/
  stoptimer(A);


}
else
  if (TRACE > 0)
    printf ("----A: duplicate ACK received, do nothing!\n");

}
else
if (TRACE > 0)
printf ("----A: corrupted ACK is received, do nothing!\n");
}

/* called when A's timer goes off */
void A_timerinterrupt(void)
{

if (TRACE > 0)
printf("----A: time out,resend packets!\n");

if (TRACE > 0)
printf ("---A: resending packet %d\n", (buffer[windowfirst]).seqnum);
tolayer3(A,buffer[windowfirst]);
/**** 1. FILL IN CODE What state should the timer be in at this point? *****/
starttimer(A,15.0);

packets_resent++;
}

/* the following routine will be called once (only) before any other /
/
entity A routines are called. You can use it to do any initialization /
void A_init(void)
{
/
initialise A's window, buffer and sequence number /
A_nextseqnum = 0; /
A starts with seq num 0, do not change this /
windowfirst = 0;
windowlast = -1; /
windowlast is where the last packet sent is stored.

new packets are placed in winlast + 1
so initially this is set to -1 */
windowcount = 0;
}

/********* Receiver (B) variables and procedures ************/

static int expectedseqnum; /* the sequence number expected next by the receiver /
static int B_nextseqnum; /
the sequence number for the next packets sent by B */

/* called from layer 3, when a packet arrives for layer 4 at B*/
void B_input(struct pkt packet)
{
struct pkt sendpkt;
int i;

/* if not corrupted and received packet is in order */
if ( (!IsCorrupted(packet)) && (packet.seqnum == expectedseqnum) ) {
if (TRACE > 0)
printf("----B: packet %d is correctly received, send ACK!\n",packet.seqnum);
packets_received++;

/* deliver to receiving application */
tolayer5(B, packet.payload);

/* send an ACK for the received packet */
sendpkt.acknum = expectedseqnum;

/* update state variables */
expectedseqnum = (expectedseqnum + 1) % 2;        

}
else {
/* packet is corrupted or out of order /
if (TRACE > 0)
printf("----B: packet corrupted or not expected sequence number, resend ACK!\n");
/
**** 3. FILL IN CODE What ACK number should be sent if the packet
was corrupted or out of order? *******/
if(expectedseqnum ==1)
{
sendpkt.acknum = 0;
}
if(expectedseqnum ==0)
{
sendpkt.acknum =1;
}

}

/* create packet */
sendpkt.seqnum = B_nextseqnum;
B_nextseqnum = (B_nextseqnum + 1) % 2;

/* we don't have any data to send. fill payload with 0's */
for ( i=0; i<20 ; i++ )
sendpkt.payload[i] = '0';

/* computer checksum */
sendpkt.checksum = ComputeChecksum(sendpkt);

/* send out packet */
tolayer3 (B, sendpkt);
}

/* the following routine will be called once (only) before any other /
/
entity B routines are called. You can use it to do any initialization */
void B_init(void)
{
expectedseqnum = 0;
B_nextseqnum = 1;
}

/******************************************************************************

  • The following functions need be completed only for bi-directional messages *
  • They do not need to be completed for this practical * *****************************************************************************/

/* Note that with simplex transfer from a-to-B, there is no B_output() */
void B_output(struct msg message)

{
}

/* called when B's timer goes off */
void B_timerinterrupt(void)
{
}

  • 写回答

1条回答 默认 最新

  • ThinkWerewolf 2018-04-20 02:51
    关注

    参看计算机网络 链路层 路由层协议 部分内容, Go back N 的方法应该就是 有 n 个 帧窗口可以等待无序到达接收。可能描述不够细节清楚,但希望有帮助。

    评论

报告相同问题?

悬赏问题

  • ¥15 shape_predictor_68_face_landmarks.dat
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料
  • ¥15 使用R语言marginaleffects包进行边际效应图绘制