您的位置:首页 > 理论基础 > 计算机网络

通信网络实验——滑动窗口协议模拟实现

2012-11-13 23:10 411 查看
一.实验目的

实现一个滑动窗口协议的数据传送部分,目的在于使学生更好地理解基本滑动窗口协议的基本工作原理,掌握计算机网络协议的基本实现技术。

二.实验原理

(1)窗口机制

滑动窗口协议的基本原理就是在任意时刻,发送方都维持了一个连续的允许发送的帧的序号,称为发送窗口;同时,接收方也维持了一个连续的允许接收的帧的序号,称为接收窗口。发送窗口和接收窗口的序号的上下界不一定要一样,甚至大小也可以不同。不同的滑动窗口协议窗口大小一般不同。发送方窗口内的序列号代表了那些已经被发送,但是还没有被确认的帧,或者是那些可以被发送的帧。

(2)1比特滑动窗口协议

当发送窗口和接收窗口的大小固定为1时,滑动窗口协议退化为停等协议(stop-and-wait)。该协议规定发送方每发送一帧后就要停下来,等待接收方已正确接收的确认(acknowledgement)返回后才能继续发送下一帧。由于接收方需要判断接收到的帧是新发的帧还是重新发送的帧,因此发送方要为每一个帧加一个序号。由于停等协议规定只有一帧完全发送成功后才能发送新的帧,因而只用一比特来编号就够了。

(3)后退n协议

由于停等协议要为每一个帧进行确认后才继续发送下一帧,大大降低了信道利用率,因此又提出了后退n协议。后退n协议中,发送方在发完一个数据帧后,不停下来等待应答帧,而是连续发送若干个数据帧,即使在连续发送过程中收到了接收方发来的应答帧,也可以继续发送,且发送方在每发送完一个数据帧时都要设置超时定时器,只要在所设置的超时时间内仍收到确认帧,就要重发相应的数据帧。如:当发送方发送了N个帧后,若发现该N帧的前一个帧在计时器超时后仍未返回其确认信息,则该帧被判为出错或丢失,此时发送方就不得不重新发送出错帧及其后的N帧。

三.实验步骤

1.编写滑动窗口协议的实现程序;

2.在模拟实现,调试并运行自己编写的协议实现程序;

3.了解协议的工作轨迹,如出现异常情况,在实验报告中写出原因分析。

四.实验报告

1.详细描述实验过程。

2.实现具体的窗口滑动协议。

实验在Fedora 16 Linux下完成。实验模拟了滑动窗口协议,服务器向客户端发送数据,客户端判断数据是否错误,错误就重传错误的帧。

主要代码如下,包含一个客户端文件和服务器文件:

/* ****************************************************************
* 文件名: client.c
* 描述: 本文件用于模拟滑窗协议客户端
* 编译: Linux: gcc -lm -o client client.c
* 可执行文件: ./client
* 作者: 段聪 01091138
******************************************************************/
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#define server_ipaddr "127.0.0.1"
/*************************************************************************
* 函数名: main
* 参数: NIL
* 返回值: NIL
* 描述: 主函数
***************************************************************************/
main()
{
int std, lfd, len, choice, cport;
char str[20], str1[20], err[20];
struct sockaddr_in saddr, caddr;
printf("输入端口号:");
scanf("%d", &cport);
std = socket(AF_INET, SOCK_STREAM, 0);
if(std<0)
perror("创建socket错误");
bzero(&saddr, sizeof(saddr));
saddr.sin_family = AF_INET;
inet_pton(AF_INET, server_ipaddr, &saddr.sin_addr);
saddr.sin_port = htons(cport);
connect(std, (struct sockaddr *)&saddr, sizeof(saddr));
while(1)
{
read(std, str, 20);
if(strcmp(str, "Exit") == 0)
{
printf("正在退出!\n");
break;
}
printf("收到: %s 错误?(1 - 是 0 - 否): ", str);
scanf("%d", &choice);
if(choice == 0)write(std, "-1", sizeof("-1"));
else
{
printf("输入发生错误序列的帧号:");
scanf("%s", err);
write(std, err, sizeof(err));
read(std, str, 20);
printf("收到传输帧: %s\n", str);
}
}
close(std);
}

/* ****************************************************************
* 文件名: server.c
* 描述: 本文件用于模拟滑窗协议服务器端
* 编译: Linux: gcc -o server server.c
* 可执行文件: ./server
* 作者: 段聪 01091138
******************************************************************/
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
//滑动窗口大小
#define SIZE 4
/*************************************************************************
* 函数名: main
* 参数: NIL
* 返回值: NIL
* 描述: 主函数
***************************************************************************/
main()
{
int std, lfd, len, i, j, status, sport;
char str[20], frame[20], temp[20], ack[20];
struct sockaddr_in saddr, caddr;
printf("输入端口号:");
scanf("%d", &sport);
std = socket(AF_INET, SOCK_STREAM, 0);
if(std<0)
perror("创建socket错误");
bzero(&saddr, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
saddr.sin_port = htons(sport);
lfd = bind(std, (struct sockaddr *)&saddr, sizeof(saddr));
if(lfd)
perror("绑定错误");
listen(std, 5);
len = sizeof(&caddr);
lfd = accept(std, (struct sockaddr *)&caddr, &len);
printf("输入要发送的文本:");
scanf("%s", str);i = 0;
while(i<strlen(str))
{
memset(frame, 0, 20);
strncpy(frame, str+i, SIZE);
printf("\n传输帧:");
len = strlen(frame);
for(j=0; j<len; j++)
{
printf("%d", i+j);
sprintf(temp, "%d", i+j);
strcat(frame, temp);
}
write(lfd, frame, sizeof(frame));
read(lfd, ack, 20);
sscanf(ack, "%d", &status);
if(status == -1)
printf("\n传输成功!");
else
{
printf("接收错误: %d", status);
printf("\n重传帧:");
frame[0] = str[status];
frame[1] = '\0';write(lfd, frame, sizeof(frame));
}
i = i + SIZE;
}
write(lfd, "Exit", sizeof("Exit"));
printf("\n正在退出!\n");
sleep(2);
close(lfd);
close(std);
}

使用gcc进行编译:

gcc -o client client.c
gcc -o server server.c

产生两个可执行文件client 和server。

运行程序

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: