资源描述
声明:仅仅用于交作业,小心与别人重复,被老师抓
问题描述:
设计一个简单的网络协议,要求有协议的功能、目标、协议的工作原理、协议算法,并编程实现
文件传输协议
协议功能:通过网络以字节形式传输文件
协议工作原理:全双工先信道传输
发送端一次发送4个字节32位。
接收端一次发送1个字节8位。
接收端缓冲区4个字节,平均分为4块。
协议详细和协议算法
1、 建立连接
先发送方端请求建立连接,字节流数据首部 00 表示请求连接。请求建立连接时2~31位无效。
如:
0
0
1
1
1
1
1
1
接收端返回字节数据0~1位为00表示同意建立连接。不同意连接则不给予回应
如:
0
0
1
1
1
1
1
1
发送端开始发送数据,接收端缓冲区一共有4块,每块大小为一个字节。
发送的字节 5~7 位表示本次发送的数据大小单位 byte
当数据发送完时,发送端发送的字节流首部 0、1位为 11 表示发送结束
发送端发送 字节流首部
0
1
2
3
4
5
6
7
状态
数据标记
缓冲区块号
本次数据长度
8
16
24
31
数据
各位说明
状态标识位
00 请求连接
01 正在发送
11 发送结束
数据标记
0 发送的数据是源数据
1 发送的数据是加密后的数据
缓冲区块号
本次发送数据长度
0~8个字节
接收端发送 字节流
0
1
2
3
4
5
6
7
标识位
缓冲区块号
标识为
00 同意建立连接
01 缓冲区已刷新
10 确认收到数据
11 确认结束
2、 开始发送
发送端发送的字节状态标识位 为01
如:发送到第1块缓冲区、大小为8 byte的数据源数据
0
1
0
0
1
1
1
1
0
1
0
1
1
0
0
0
1
1
0
1
0
1
0
0
1
0
1
0
1
0
0
1
8byte 数据
保证数据的可靠性,发送时将源数据发一遍,将加密后的数据也发一遍,源数据和加密后的数据的差别由数据标记位区分。0表示发送的数据是源数据,1表示发送的数据是加密后的数据。
接收端接收数据时将数据接收到的源数据加密与接收到在发送端加密的数据比较,不同则把接收到的数据丢弃。假如相同则给发送端回一个数据,表示该缓冲区块的数据接收成功,并且不再接收往该缓冲区块的数据。
如:第 2 缓冲块
1
0
1
1
0
1
1
1
接收端接受数据后不再发那个字节数据。当缓冲区填满以后发送端不再发送,接收端将缓冲区的数据则写入设备,并给发送端一个回应。表示可以发送端继续发送数据了。
如:
0
1
1
1
1
1
1
1
发送端在发送数据后假如接收不到接收端的确认信息,则等待一个时间后继续发送。
3、 发送完成
发送端在数据发送完后发送的结束标识字节,并等待接收端回应,如一段世间还不回应则继续发送。
如:
1
1
1
1
1
1
1
1
接收端回送确认结束
如:
1
1
1
1
1
1
1
1
编程实现
#include<iostream>
using namespace std;
#define SEND_SIZE 32
#define BACK_SIZE 8
//用int型数组模拟数据的位
void SendEnd(const int* recData); //发送端处理函数
void RecevieEnd(const int* recData); //接收端处理函数
void encode(int* data); //加密函数
int pool[4][SEND_SIZE-BACK_SIZE];
int main()
{
int data[SEND_SIZE] = {0,0};
SendEnd(data);
return 0;
}
/*发送端请求
00 请求连接
01 正在发送
11 发送结束
接收端回送
00 同意建立连接
01 缓冲区已刷新
10 确认收到数据
11 确认结束
*/
//发送端处理函数
void SendEnd(const int* recData)
{
//recData 从接收端回送的的数据
int sendData[SEND_SIZE]; //往接收端发送的数据
if(recData[0]==0 && recData[1]==0)
{
// 00 同意建立连接
//往第二块缓冲区发送的源数据
sendData[0] = 0;sendData[1] = 1;
sendData[2] = 0;
sendData[3] = 1;sendData[4] = 0;
sendData[5] = 0;sendData[6] = 1;sendData[7] = 1;
int data[24] = {1,1,0,1,0,1,1,0, 0,1,0,0,0,0,1,0, 1,0,0,1,0,1,1,0};
for(int i=0; i<SEND_SIZE-BACK_SIZE; i++)
sendData[i+BACK_SIZE] = data[i];
cout<<"开始给接收端发送源数据大小:"<<sendData[5]*4+sendData[6]*2+sendData[7]+1<<"B 缓冲块:"<<sendData[3]*2+sendData[4]<<endl;
RecevieEnd(sendData);
//往第二块缓冲区发送加密后数据
sendData[2] = 1;
encode(data); //将数据加密后在发一次
for(int i=0; i<SEND_SIZE-BACK_SIZE; i++)
sendData[i+BACK_SIZE] = data[i];
cout<<"开始给接收端发送加密后的数据大小:"<<sendData[5]*4+sendData[6]*2+sendData[7]+1<<"B 缓冲块:"<<sendData[3]*2+sendData[4]<<endl;
RecevieEnd(sendData);
} else if(recData[0]==0 && recData[1]==1)
{
// 01 缓冲区已刷新
cout<<"发送端: 好啊,继续发送..."<<endl;
cout<<"文件传输结束,发送端请求结束"<<endl;
sendData[0] = 1;sendData[1] = 1;
RecevieEnd(recData);
} else if(recData[0]==1 && recData[1]==0)
{
// 10 确认收到数据
cout<<"发送端: 我知道"<<"第"<<recData[3]*2+recData[4]<<" 块缓冲区的数据成功接收了"<<endl;
cout<<"文件传输结束,发送端请求结束"<<endl;
sendData[0] = 1;sendData[1] = 1;
RecevieEnd(recData);
} else
{
// 11 确认结束
cout<<"发送端: 断开连接"<<endl;
}
}
//接收端处理函数
void RecevieEnd(const int* recData)
{
//recData 从发送端发送的数据
int sendData[BACK_SIZE]; //往发送端回送的数据
if(recData[0]==0 && recData[1]==0)
{
// 00 请求连接
cout<<"发送端请求连接"<<endl;
sendData[0] = 0;sendData[1] = 0;
} else if(recData[0]==0 && recData[1]==1)
{
// 01 正在发送
int piece = recData[3]*2+recData[4]; //缓冲块号
int size = recData[5]*4+recData[6]*2+recData[7]+1; //本次发送数据大小
//cout<<piece<<" sfsfsf"<<endl;
if(recData[2] == 0)
{
//接收源数据
cout<<"接收到源数据数据大小:"<<size<<"B 缓冲块:"<<piece<<endl;
//将数据存到指定的缓冲区块
cout<<"收到的数据为:"<<endl;
for(int i=8; i<SEND_SIZE; i++)
{
pool[piece][i-8] = recData[i];
cout<<recData[i]<<" ";
}
cout<<endl;
} else {
cout<<"接收到加密后的数据大小:"<<size<<"B 缓冲块:"<<piece<<endl;
int temp[SEND_SIZE-BACK_SIZE];
int i;
for(i=0; i<SEND_SIZE-BACK_SIZE; i++)
temp[i] = pool[piece][i];
encode(temp);
for(i=0; i<SEND_SIZE-BACK_SIZE; i++)
{
if(temp[i] != recData[i+8])
break;
}
if(SEND_SIZE-BACK_SIZE==i)
{
cout<<"接收端: 正确成功接收"<<endl;
sendData[0] = 1;sendData[1] = 0;
for(int j=2; j<BACK_SIZE; j++)
sendData[j] = recData[j];
SendEnd(sendData);
} else
{
cout<<"接收端: 没有正确接收,不给予回应"<<endl;
}
}
} else if(recData[0]==1 && recData[1]==0)
{
//
} else
{
// 11 发送结束
cout<<"发送端发送结束,接收端回应结束"<<endl;
sendData[0] = 1;sendData[1] = 1;
SendEnd(sendData);
}
}
void encode(int* data)
{
int code[SEND_SIZE-BACK_SIZE] = {1,0,1,1,0,1,1,0, 1,0,1,0,1,0,1,0, 1,0,1,0,1,1,1,0};
for(int i=0; i<SEND_SIZE-BACK_SIZE; i++)
data[i] = data[i]&code[i];
}
编译环境windows 编译器vc2008
执行结果
总结
此文件传输协议还有很多不足的地方
如:
1、 两次握手连接无法保证正确连接
2、 当缓冲去未满时无法继续发送
3、 程序也没有完全模拟出来
7
展开阅读全文