简单文件传输软件(一)

实验目的

  1. 应用层文件传输的原理
  2. 传输层协议选用

  用户通过一个FTP用户代理和FTP交互。用户提供远程主机的主机名,本地的FTP客户进程建立一个到远程主机FTP服务器进程的TCP连接。用户提供用户标识和口令,作为FTP命令的一部分在该TCP连接上传送。服务器向用户授权,用户可以将存放在本地文件系统中的多个文件复制到远程文件系统。HTTP和FTP都是建立在TCP上的应用层文件传输协议。FTP的控制信息是带外传送的。HTTP是带内发送控制信息的。
FTP使用了两个并行的TCP连接来传输文件:
  1.控制连接:用于在两主机之间传输控制消息,如用户标识、口令、改变远程目录的命令以及存放/获取文件的命令
  2.数据连接:用于实际发送一个文件
用户主机与远程主机开启一个FTP会话时:
  1.FTP的客户端在服务器21号端口与服务器端发起一个用于控制的TCP连接
  2.FTP的客户端通过控制连接发送用户的表示和口令,发送改变远程目录的命令
  3.当FTP的服务器端从该连接上收到一个文件传输的命令后,就发起一个到客户端的TCP数据连接
  4.FTP在数据连接上传送一个文件,然后关闭该连接
注意:
  1.在同一个会话期间,如果用户还需要传输另外一个文件,FTP打开另一个数据连接
  2.对于控制连接,贯穿于整个会话期间
  3.FTP服务器必须在整个会话期间保留用户的状态,是有状态的
FTP命令和回答:
  以7比特ASCII格式在控制连接上传送。每个命令由4个大写字母ASCII字符组成
  User username:向服务器传送用户标识
  PASS password:向服务器传送用户口令
  LIST:用于请求服务器会送当前远程目录中的所有文件列表,文件列表在新建的数据连接上传送
  RETR filename:用于从远程主机当前目录检索文件,该命令引起远程主机发起一个数据连接,并经该数据连接发送所请求的文件
  STOR filename:用于在远程主机的当前目录上存放文件
典型的回答:
  331 Username OK , Password required
  125 Data connection already open; transfer starting
  425 Cam’t open data connection
  452 Error writing file

  1. 应用层协议设计

  为了让数据能够按时间序列存储以及按时间序列设计索引取出数据,并且能够在应用层对数据包进行校验,能够用过状态机编程以实现数据的检验,重传,成功发送等多种状态。
具体设计如下:
时间戳字段,字段名time_stamp, 数据格式 time_t, 由七个uint16_t构成的结构体,
分别表示年-月-日-时-分-秒-毫秒。时间戳字段一方面用于作为数据传输的校验功能,另一方面用于数据的存储与按时间回放,将时间戳作为key构建索引。
1秒几帧图像字段,字段名fps, 数据格式uint16_t,表示一秒由几帧图像,用于在 应用层将图像数据的拼接。
帧数字段,字段名frame,数据格式uint16_t, 表示当前图像数据属于第几帧,和 fps字段配合使用。按序将数据包拼接。
设备通道号字段,字段名channel,数据格式uint16_t,由于数据是多源传感器来的,因此可能出现同一时刻不同设备的数据需要存储,因此需要加设备通道号字段
图像包序号字段,字段名index,数据格式uint16_t, 标记当前数据包的序号,为了检验接收端是否完整接收数据包
数据包大小字段,字段名size,数据格式uint32_t, 标记当前数据包实际发送了多少字节的数据,为了接收端校验是否完整接收数据包
设计了4个标志位,结合状态机编程以实现应用层的校验,重传,确认机制,由于状态位用0, 1即可表示,因此设计成位图(bitmap)存储,可以节省32倍空间
确认号标志位,字段名ACK, 数据格式bitmap,数据包是否接收标志位,如果已经接收则字段值设为1,如果没有则设为0

//使用状态机例子,利用位运算实现状态转换:

#define ACK 0x01

#define NOACK 0x00

Package package;//收到的数据包

if (数据包传输成功) {

package.ack |= ACK;

} else {

package.ack |= NOACK;

}

if (package.ack & ACK) {

//成功传输后续处理

} else if (package.ack & ACKNO) {
//传输失败,丢弃数据 or 重传数据包

}

重传标志位,字段名RST, 数据格式bitmap,数据包如果接收端经校验之后丢包,则开启重传标志, 发送端开始重传数据包代码,需要重传则设为1, 否则设为0
例子可参考ACK
检验位,字段名CHECK, 数据格式bitmap,接收端完成对数据包大小和序号的校验之后,如果正确则将校验位置为1,代表校验成功,否则代表校验失败,需要 经过重传处理
例子可参考ACK
完成标志位,字段名FINISH,数据格式bitmap,接收端经校验后收到完整的数据包,则完成标志位的值置为1,表示当前数据包完成发送,可开启下个数据包的发送,否则一直值为0,发送端与接收端继续保持当前数据包的传输
例子可参考ACK
保留标志位,字段名OFFSET,可扩充字段,当程序需要加入新的状态的时候可以直接增加标志位,而不用改变之前的数据结构的内存布局,同时作为偏移量补充之前状态位。
原始数据,字段rawdata,数据类型位uint16_t[],大小控制在1000字节/包以内,考虑到底层传输效率与拆包丢包,数据包所有字节加一起应小于链路层的最小传输单元(1500字节),去除网络层的ip包头(20字节,用于寻址),传输层的tcp包头(20字节,用于可靠传输)/udp包头(8字节,基本多路复用/多路分解),应用层包头(31字节),因此一个包的数据应控制在1000字节。


协议内存设计
//数据包设计
//日期

typedef struct Date {

    bool use_string;

    uint16_t year;

    uint16_t month;

    uint16_t day;

    uint16_t hour;

    uint16_t minute;

    uint16_t second;

    string time; // YYYY-MM-DD h-m-s

} Date_t;

//通道

typedef enum Channel {

    A = 1,

    B = 2,

C = 3,

D = 4

} Channel_t;

//1秒6帧图像

typedef enum Frame {

    ONE = 1,

    TWO = 2,

    THREE = 3,

    FOUR = 4,

    FIVE = 5,

    SIX = 6

} Frame_t;

 

typedef struct PackageHead {

    Date_t time_stamp; //时间戳

uint16_t fps;//1秒几帧图像

    Frame_t frame; //帧数

    Channel_t channel; //通道编号

    uint8_t index; //图像包序号,一帧图像会拆包,底层有最大传输单元限制,一个包最多有1500字节 - TCP/UDP包头 - 应用层协议包头

    uint16_t data_size; //传输的数据包大小

    bool reliable; //可靠传输标志位

    bool ack; //确认号标志位

    bool rst; //重传标志位

    uint16_t seq; //udp包序号

    bool finish; //一帧图像是否传完

    uint8_t offset[16]; //16字节可扩容字段

} PackageHead;

 

typedef struct Package {

    PackageHead head; //包头

    uint8_t raw_data[1000]; //最好不要超过1000字节

} Package;

 

//位图设计
class Bitmap {

public:

    Bitmap(int size, int _key = 32)

    {

        key = _key;

        buffer.resize(size / key + 1);

    }

    void insert(int value)

    {

        int seg_index = value / key;

        int index = value % key;

        buffer[seg_index] |= (1 << index);

    }

    void get(int value)

    {

        int seg_index = value / key;

        int index = value % key;

        if (buffer[seg_index] & (1 << index)) {

            cout << value << " is in bitmap" << endl;

        } else {

            cout << value << "is not int bitmap" << endl;

        }

    }

 

private:

    vector<uint32_t> buffer;

    int key;

};

//状态机编程
#define ACK 0x01

#define NOACK 0x00

Package package;//收到的数据包

if (数据包传输成功) {

package.ack |= ACK;

} else {

package.ack |= NOACK;

}

if (package.ack & ACK) {

//成功传输后续处理

} else if (package.ack & ACKNO) {
//传输失败,丢弃数据 or 重传数据包

}
  1. 误码

需求

编写发送软件和接收软件,将指定文件夹的文件发送到另一个文件夹:
1.支持Windows和Linux路径名(服务器端和客户端不在同一平台)
2.文件夹下所有子文件夹也即时传输
3.误码文件不输出,重传失败后记录并告诉客户
4.文件包括可执行文件、图像、视频、Office文档、文本
5.健壮性(输入)
6.支持压缩提高效率
7.下次传输根据差异更新文件(中断或结束)

接口

服务器命令行:

1.文件路径名
2.IP地址
3.端口号

客户端命令行:

1.文件路径
2.IP地址
3.端口号

解码器命令行:

client/opt/var 192.168.1.1.9999

开发语言:

C++

评分标准

传输速率、软件质量、图形用户界面

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,377评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,390评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,967评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,344评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,441评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,492评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,497评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,274评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,732评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,008评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,184评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,837评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,520评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,156评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,407评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,056评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,074评论 2 352

推荐阅读更多精彩内容

  • 个人认为,Goodboy1881先生的TCP /IP 协议详解学习博客系列博客是一部非常精彩的学习笔记,这虽然只是...
    贰零壹柒_fc10阅读 5,052评论 0 8
  • 1.TCP报头格式 UDP报头格式 TCP报头格式 UDP报头格式 具体的各部分解释看 TCP报文格式详解 - ...
    杰伦哎呦哎呦阅读 2,448评论 0 5
  • 本文将针对ftp系统共介绍6部分,分别是ftp协议(双重连接:控制和数据连接),ftp的主动和被动模式(区别/使用...
    robot_test_boy阅读 14,248评论 6 19
  • FTP服务概述 简单FTP构建及访问 VSFTP服务基础 用户禁锢、黑白名单 FTP并发及带宽限制 一、FTP服务...
    紫_轩阅读 7,596评论 3 25
  • 房子还有10天就到期了,之前一直都没有找,总觉得很好找的样子。结果今天一找起来才发现是一件多么心塞的事情。来北京马...
    午夜华尔兹阅读 262评论 0 0