基于UDP的文件传输软件 (C#)

选了一门软件开发案例的选修课,得到一项多选一大作业,我们选择了“基于UDP的文件传输系统”这个作业,然后经过需求分析和概要设计,进入编码阶段,因为作业要求有界面,个人认为用C#编写桌面软件比较容易,就选择了C#而非Java做这个作业(主要是Java编写桌面软件我不会)。
这篇博文的目的在于解释大作业的结构,放上一些需求分析和概要设计的成果,结合代码,所以说踩过哪些坑,如何设计的软件结构,代码下载地址将会放在文章结尾。
说来惭愧,负责这个作业的分析和设计的,是我组长(我是副组长兼组员,笑),我负责上来就编码,这完全没有遵循软件开发的规范,事后,我觉得应该补救一下,所以打算用这篇文章完成一些分析与设计做的事情。

项目要求

完成一个局域网内的基于UDP的文件传输系统,该软件有客户端与服务端,服务端绑定IP、端口,监听接收文件的消息,客户端连接服务端,向其发送选中文件,发送文件过程中允许两端终端文件传输。同时需要支持多个客户端的文件发送。
附两张老师需求文档中界面的截图:

需求分析,划分功能点

在项目要求和图片中把很多点都列举出来了,这里列个表

  • 选择IP、端口,服务端需要绑定IP、端口,客户端需要连接到服务端
  • 通信,客户端和服务端可以通信,不仅是隐式的,还有显式的主动收发消息
  • 文件选择,客户端需要选择文件
  • 文件传输,客户端需要发送文件
  • 停止文件传输,客户端、服务端都可以停止文件的发送
  • 文件接收、写入磁盘,服务端需要接收文件,写入磁盘
  • 显示文件发送情况,客户端需要显示当前文件已发送多少,所占比例是多少
  • 多线程支持,一个服务端需要同时应对多个客户端

技术分析

  1. 基于UDP,服务端还绑定IP端口,当时我一想,钻了个牛角尖:使用同一个端口怎么可能支持多个客户端?期间还想起了学习计算机网络的知识,UDP的Socket只通过本机的IP和端口标识一个连接,这样的话,岂不是所有客户端的连接,只要接入同一个服务端的IP和端口,就只能被识别为一个连接了?数据怎么传,做不成吧。
    问了老师,老师只回答了用多线程,并没有解决UDP使用同一个IP端口的问题。
    后来做起来,渐渐想清楚了,绑定一个IP和端口肯定是不行的,这其实是让我们手动模拟TCP的Socket.accept函数,每次接到一个连接请求,就重新分配一个端口号用于传输。
  2. 从上面的需求界面可以看到,街面上需要显示当前传输文件的进度,进度是实时更新的。这其实是一个难点。因为传输肯定是要放到UI线程之外来做的,否则UI会卡死,但是UI控件的更新却只能由UI线程来做,这是矛盾的。自然,这种矛盾不仅我们遇到过,无数用C#写桌面程序的人都遇到过,查一下,就有了答案,通过使用SynchronizationContext,将希望UI线程更新的信息,借由同步上下文使用消息队列发送给UI线程,交由UI线程来做。
  3. 还是基于2中的问题,实时更新,其实是一个细粒度的事情,这表示底层Socket发送的过程中要向上层反馈消息,消息再由消息队列交付给UI线程,那么底层向上层发送消息怎么实现呢?自己写消息队列然后上层轮询,可以,但这个消息队列就要手写了。方法应该有很多种,我想到了C#的语法——委托。可以让上层实现消息交付给UI线程的函数,而底层持有这个函数的委托(相当于函数指针),这样底层既可以调用直接调用上层的函数了。

这个时候就突然想起了从哪儿看到的,C#常用于开发桌面应用,所以才有了委托这个语法。确实,委托就像抛向底层的钩子,UI的事情只能上层来做,通过这些钩子却可以让底层也能做。

系统设计与模块设计

这两部分其实是边写程序边修改的,程序写好了,设计也配套做好。原因是我想早早实践,这样的流程不符合软件开发的传统模型,比如瀑布流等,但是似乎符合敏捷开发,当然这是给自己贴金,不写文档不等于敏捷开发。

时序图

我组长总结的系统设计图:

上图是我组长画的系统设计图,整个程序可以分出Server和Client两个头,两个头界面和内部逻辑有些不同,相同的地方向下沉,沉到下一层的Control里,Control里有信息控制、文件发送、文件接收等主要3个类,分为3个模块。

  • 其中MsgCtrl自成一个模块,主管信息收发。
  • FileSendUDPClient两个类为一个功能,主管文件发送相关。FileSend控制UDPClient
  • FileRecUDPServer两个类为一个功能,主管文件接收相关。FileRev控制UDPServer
  • 此外还有一个Util工具类,负责定义常量抛出一些公用方法。

下面是各个类的介绍:

MsgCtrl

内部封装一个UDP的Sokcet,用于发送、接收消息
消息按类型分为系统、文件信息、文件控制、端口消息、用户消息,发送时将消息类型和内容拼接成字符串发送,接收后拆分。
函数介绍:

  • MsgCtrl():初始化
  • sendMsg(msg,flag):将类型与消息拼接,发送消息。
  • String[] reciveMsg()接收消息并且拆分消息类型与内容

UDPClient

用于发送一个文件,内部封装了一个Socket
函数介绍:

  • UDPClient(IP,Port...):初始化一个Socket,以及其他内部属性
  • sendFile():读取文件,分块,发送文件,并且借用构造器传入的委托(类似于函数指针)更新Client端界面显示
  • stopSend():停止发送文件
  • sendDatasendFile内部调用了它,用于分块发送数据

UDPServer

用于一个接收文件
函数介绍:

  • UDPServer(IP,Port):初始化Socket
  • reciveFile:接收文件,拼接文件,写入磁盘
  • reciveDatareciveFile内部调用了它,用于接收分块的一块数据
  • stopRev不同于UDPClient,UDPServer的stopRev用于UDP超时停止接收数据

FileSend

用于管理文件发送
函数介绍:

  • sendFile(UDPclient,filename,filePath):用于新开线程,发送指定文件
  • stopSend:用于取消发送最近发送的文件

FileRev

用于管理文件接收
函数介绍:

  • reciveFile(UDPserver,filename,filePath,fileSize):用于新开线程,接收指定文件
  • stopRev:用于停止接收最近接收的文件,内部其实是接收完后删除了指定文件

Util

用于规定一些公共变量,以及工具方法
函数介绍:

  • 各const String变量:用于分类msg的种类
  • checkIP(IP,prot):用于检测IP、port是否合法
  • newThread:用于开启新线程
  • randomPort:用于产生随机端口供新线程的UDP连接使用

至此呢,应该说需求分析和设计就算是完成了,编码工作也同步完成,下面说下不足,也就是编码没考虑周全的地方

待改进

  • 界面的问题:C#竟然没有官方的IP地址栏的控件,这导致界面上IP地址和端口的Input极丑还不好用,需要改进
  • 输入数据的检测:如果服务端填写的不是本机IP会怎样?肯定不行是吧,但是我没有做这方面的检测
  • 多线程管理:现在的程序,是开了线程就不管了,等着线程里的任务跑完或者超时杀死线程。其实在Util类里我是放过一个链表来收集线程的,并且有退出杀死链表中所有线程的函数,但细粒度的管理并不知道怎么做
  • 功能划分,或者模块划分:其实写起来还是有些东西不知道划分在哪儿,比如MsgCtrl,是客户端服务端使用同一个类,还是特化出两个不同类,代码结构还要改进;此外,MsgCtrl应该单拿出来的,我将其方法写在了界面代码里,增加了耦合。
  • 随机端口:随机端口部分,可以用,但是没有检测端口被抢占了的问题,应该将使用中的端口放入一个Set,每次随机的端口需要先判断是否已使用

好,上面的内容一看完,这个程序除了能跑通就没优点了。
其实这个程序已经重构过一次了,先前那一版,因为脑袋里没有全局的设计,导致有几个部分功能划分重叠,现在代码结构更清爽点。

源码地址

最后,等作业检查完放github地址:github:基于UDP的文件传输软件 (C#)

基于UDP的文件传输软件 (C#)相关推荐

  1. ftp可以传输什么类型文件_为什么文件传输软件总让数据“没有安全感”?

    最新的<大数据安全市场-全球机会分析和行业预测>报告显示:到2027年,整个大数据安全市场将增长到644亿美金.这对整个大数据营销市场来说,是一个好消息!但在数据极速增长的同时,传输安全. ...

  2. 最快速的文件传输软件,解析镭速文件传输软件

    想到每天都需要进行文件传输,就会烦躁,要是有一夸最快速的文件传输软件的话,这样就可以节省大量的时间了,那么针对于用户的这一个需求,我们来介绍一下镭速的文件传输软件,看是否是那么快,快到你难以置信. 文 ...

  3. 基于Socket的文件传输(使用CSocket类)

    本软件使用MFC采用面向对象的方法实现了基于Socket的文件传输.这是原来研究生课程的结课作业,实现了Socket的发送和接收,以及读取ini配置文件等操作.使用了CSocket类 以下是当时结课作 ...

  4. 大文件传输软件的优势你了解吗?

    2012年以来,大数据(big data)一词越来越多地被提及,人们用它来描述和定义信息爆炸时代产生的海量数据,并命名与之相关的技术发展与创新.数据正在迅速膨胀并变大,它决定着企业的未来发展.企业面临 ...

  5. 镭速raysync介绍文件传输软件的进史

    第一个文件通过可移动媒体交换.在1980年代中期,异步调制解调器接管了双同步停止的地方.然后,在九十年代,互联网改变了使用持久连接通过HTTP,FTP和SMTP在企业之间传输文件的游戏.随后几年出现了 ...

  6. 这款文件传输软件每隔10秒就会发起文件同步——镭速传输

    为了解决大文件快速同步备份问题,镭速传输基于Raysync超高速传输协议,开发了GB/TB级大文件同步备份功能,速度可提升30倍以上. 镭速传输的文件同步功能,有两种模式,如下: 第一种:选择&quo ...

  7. 什么是文件共享软件?文件传输软件如何共享?

    它是一个文件共享软件应用程序,可让强大的数据保护层下将任何大小的文件发送到世界上的任何地方.以光速发送和共享无限数量的文件.可以提交门户并使用语言,品牌,存储等自定义门户.可以选择一个存储点,例如文件 ...

  8. QT中级(6)基于QT的文件传输工具(2)

    QT中级(6)基于QT的文件传输工具(2) 本文实现第一步 1 新增功能 2 运行效果 3 实现思路 4 源代码 实现这个文件传输工具大概需要那几步? 实现多线程对文件的读写 实现TCP客户端和服务端 ...

  9. 写了一个文件传输软件

    大家好,我是涛哥. 最近遇到这样一件事情,有一个大文件,用微信从电脑A传输到电脑B,结果微信提示文件过大.这点小事情,略微有点郁闷. 解决办法肯定是有的,比如下载一个文件传输软件,然后传送大文件.不过 ...

  10. java p2p文件传输_P2P文件传输软件的设计与实现

    摘要:本系统是在深入了解P2P技术和JAVA实现平台的基础上,设计实现的基于JAVA的P2P文件传输软件,在局域网内实现点对点的文件传输功能.本系统的优点是在一个网络内每个Windows平台的客户机只 ...

最新文章

  1. java 做登录跳转404_springboot 访问路径错误跳转到404(实现方法一)
  2. gnuplot_i 文件的说明,翻译成的中文
  3. 信息奥赛一本通(1310:【例2.2】车厢重组)
  4. Jquery Mobile 画面导航栏共用的实现方法
  5. 如何使用Docker、Docker-Compose和Rancher搭建部署Pipeline(二)
  6. CentOS8 安装 Docker
  7. 载入样式表单出错: 分析 XSLT 样式表单失败
  8. DELPHI 文件压缩加密
  9. 数据结构与算法分析——Hash表
  10. 天猫精灵开发技能【2】
  11. typedef struct LNode* list和struct LNode有什么区别?
  12. 论文之目录的页码修改
  13. 08_MySQL的函数
  14. Mat 无法解析dump文件:Dominator tree not available. Open the Dominator Tree or delete indices and parse aga
  15. 玉米生吃好还是熟吃好 各种情况分析
  16. 做量化交易的第一步,Python爬取股票数据
  17. 深耕游戏后服务 虚贝战略再升级
  18. Equalize Them All
  19. Python — 词汇表(一)
  20. 地铁自动驾驶模型,地铁列车牵引系统整车模型。

热门文章

  1. 深圳名校最新出炉 学校学区房房价飙升-查查吧深圳学区房地图
  2. shiro整合ehcache Cannot resolve reference to bean 'securityManager' while setting bean property 'secur
  3. BankNext 微服务:案例研究
  4. 4针串口线接法图_9针rs232串口接线图以及接线方法
  5. Servlet和Servlet容器概念
  6. [MacOS][Google Chrome 浏览器] 鼠标右键需要双击才能弹出菜单
  7. 安卓逆向,Python爬虫,网页逆向和其他学习计划
  8. 存在哪些域名后缀种类?哪个后缀比较好?
  9. ILSVRC2016
  10. MATLAB视频转图片保存