网络课程设计-tcp数据包的发送和接收

合集下载

tCp流程

tCp流程

tCp流程TCP流程(Transmission Control Protocol)是一种面向连接的、可靠的、基于流的传输协议,用于在网络中传输数据。

TCP流程主要包括:建立连接、数据传输和连接终止。

建立连接:1. 客户端发送一个带有SYN(同步)标志的数据包到服务器,请求建立连接。

2. 服务器收到请求后,发送一个带有SYN和ACK(确认)标志的数据包给客户端,表示同意建立连接。

3. 客户端收到服务器的数据包后,发送一个带有ACK标志的数据包给服务器,表示连接成功建立。

4. 服务器收到客户端的ACK后,连接建立完成,双方可以开始进行数据传输。

数据传输:1. 数据发送端将要发送的数据分割成合适的数据包,并加上序列号发送给接收端。

2. 接收端收到数据包后,对数据进行重新排序和校验,确保数据的完整性。

3. 接收端发送一个带有ACK标志的数据包给发送端,表示收到了数据。

4. 发送端收到ACK后,继续发送下一个数据包。

5. 如果发送端没有收到ACK或者收到了ACK超时的错误信息,需要重新发送数据包。

连接终止:1. 当发送端传输完所有的数据后,发送一个带有FIN(结束)标志的数据包给接收端。

2. 接收端收到FIN后,发送一个带有ACK标志的数据包给发送端,表示接收到了结束请求。

3. 接收端关闭接收通道,不再接收数据,但仍然可以发送数据。

4. 发送端收到ACK后,关闭发送通道,并且等待接收端传来的数据完全接收完毕后才关闭连接。

5. 接收端将剩余的数据都接收完毕后,发送一个带有FIN标志的数据包给发送端。

6. 发送端收到FIN后,发送一个带有ACK标志的数据包给接收端,表示接收到了结束请求。

7. 接收端收到ACK后,关闭连接,终止传输。

TCP流程通过建立连接、数据传输和连接终止的过程,保证了数据的可靠传输。

其中,连接的建立和终止通过三次握手和四次挥手的过程完成,确保传输的可靠性和完整性。

数据传输过程中,通过分割数据包、重新排序和校验、确认和超时重传等机制,保障数据的完整性和准确性。

tcp发包机制

tcp发包机制

tcp发包机制TCP(Transmission Control Protocol)是一种可靠的、面向连接的协议,用于在计算机网络中传输数据。

它通过一系列的机制来确保数据的可靠性和完整性,使得数据能够按顺序到达目的地。

TCP使用三次握手的机制来建立连接。

发送方首先向接收方发送一个带有SYN标志的数据包,表明请求建立连接。

接收方收到后,回复一个带有SYN和ACK标志的数据包,表示接收方愿意建立连接。

最后,发送方再回复一个带有ACK标志的数据包,表示连接已建立。

这个过程就像两个人握手一样,互相确认彼此的存在和愿意建立连接。

接下来,TCP使用滑动窗口的机制来管理数据的传输。

发送方将数据分割成多个报文段,并按顺序发送给接收方。

接收方在收到报文段后,会发送一个确认报文段给发送方,表明已经成功接收到数据。

如果发送方没有收到确认报文段,就会重新发送数据,确保数据的可靠性。

同时,TCP还会根据网络的拥塞情况动态调整滑动窗口的大小,以提高数据传输的效率。

除了滑动窗口,TCP还使用序列号和确认号的机制来保证数据的顺序和完整性。

发送方在发送数据时,会给每个报文段分配一个序列号,接收方在接收数据时,会按序列号的顺序重新组装数据。

同时,接收方会给发送方发送一个确认号,表示已经成功接收到数据。

如果发送方没有收到确认号,就会重新发送数据,保证数据的完整性。

TCP使用四次挥手的机制来关闭连接。

发送方首先发送一个带有FIN标志的数据包,表示不再发送数据。

接收方收到后,发送一个带有ACK标志的数据包,表示确认收到FIN。

然后,接收方再发送一个带有FIN标志的数据包,表示自己也不再发送数据。

通过以上的机制,TCP确保了数据的可靠性和完整性。

它是一种非常重要的协议,广泛应用于互联网和各种计算机网络中。

无论是浏览网页、发送电子邮件还是下载文件,都离不开TCP的支持。

它的出现极大地促进了信息的传输和共享,使得人们能够更加方便地进行各种网络活动。

计算机网络课程设计报告文件传输协议的简单实现

计算机网络课程设计报告文件传输协议的简单实现

课程设计课程名称计算机网络课程设计题目名称文件传输协议的简单设计与实现学生学院专业班级___ _学号学生姓名______ _________指导教师______ _____2010 年 1 月 5 日设计摘要关键词:SOCKET编程,FTPclient/server程序摘要:本课程设计包含了文件传输协议的简单设计与实现。

文件传送是各种计算机网络实现的基本功能,文件传送协议是一种最基本的应用层协议按照客户/服务器的模式进行工作,提供交互式的访问,是INTERNET使用最广泛的协议之一。

文件传输协议的简单设计与实现建立在计算机网络实验环境TCP/IP 网络体系结构之上,使用socket 编程接口编写两个程序,分别为客户程序(client.c)和服务器程序(server.c),实现下述命令功能:get , put, pwd, dir, cd, ?, quit 等,利用了已有网络环境设计并实现简单应用层协议。

本设计包括了具体设计任务,基本思路及所涉及的相关理论,设计流程图,调试过程中出现的问题及相应解决办法,实验运行结果,核心程序,个人体会及建议等。

目录1、文件传输协议的简单设计与实现------------------------------181. 1 具体设计任务----------------------------------------------18 1.2 基本思路及所涉及的相关理论--------------------------------181.2.1基本思路-------------------------------------------------182.2.2 相关理论--------------------------------------------18 1.3设计流程图------------------------------------------------191.4实验运行情况----------------------------------------------191.5 核心程序--------------------------------------------------222.5.1 服务器(sever)程序---------------------------------222.5.2 客户(client)程序----------------------------------291.6心得体会-----------------------------------------------------------------------------37参考文献--------------------------------------------------------382、文件传输协议的简单设计与实现2. 1 具体设计任务计算机网络实验环境建立在TCP/IP 网络体系结构之上。

计算机网络技术第四版课程设计

计算机网络技术第四版课程设计

计算机网络技术第四版课程设计一、设计题目本次计算机网络技术课程设计的题目是“基于TCP协议的文件传输程序实现”。

二、设计目的计算机网络技术是网络工程专业的核心基础课程之一,课程涉及到计算机网络领域的各个方向,例如网络协议、网络体系结构、路由协议、网络安全等。

通过本次课程设计,旨在让学生深入了解TCP协议的应用,掌握TCP协议的实现过程和技术要点,提高学生对计算机网络技术的理解和应用能力。

三、设计要求实现一个基于TCP协议的文件传输程序,要求如下:1.接收方和发送方分别处于不同的机器上。

2.文件传输过程通过TCP协议完成。

3.实现断点续传功能。

4.通过命令行界面输入传输文件的路径和传输模式(上传/下载)等必要信息。

四、设计流程1. 建立网络连接建立TCP连接是实现文件传输的第一步,需要使用Python的socket库实现。

按照TCP三次握手的规则,建立与对方的链接。

2. 传输文件使用Python的文件读取方式,将要传输的文件读取至内存中。

使用TCP协议,将文件分成多个数据块,依次传输至对方机器。

3. 断点续传在传输文件的过程中,可能会出现意外断开连接的情况。

为了实现断点续传功能,传输过程中需要保存已经传输的文件块,当重新建立连接后继续传输。

4. 命令行控制实现一个命令行界面,通过命令行输入文件传输的相关信息,例如待传输文件的路径、传输模式(上传/下载)等信息。

通过分析用户的操作,执行相应的文件传输操作,并在命令行上显示传输过程的相关信息。

五、技术要点1.Python Socket编程2.TCP协议3.文件读取和写入4.断点续传5.命令行控制六、设计结论通过本次基于TCP协议的文件传输程序实现的计算机网络技术课程设计,我们深入了解了TCP协议的应用过程,掌握了TCP协议的实现技术要点,并实现了文件传输过程中常见的断点续传功能和命令行控制。

这些技术点均是计算机网络技术课程中的重点内容,对我们深入学习和理解计算机网络技术的概念和应用具有重要的帮助和启示。

tcp实验报告

tcp实验报告

tcp实验报告TCP实验报告一、实验目的TCP(Transmission Control Protocol)是一种面向连接的、可靠的传输协议,它在互联网通信中扮演着重要的角色。

本实验旨在通过实际操作和观察,深入理解TCP协议的工作原理和特点。

二、实验环境1. 操作系统:Windows 102. 编程语言:Python3.93. 实验工具:Wireshark三、实验步骤与结果1. 建立TCP连接通过Python的socket库,我们可以轻松地创建TCP连接。

在本实验中,我们编写了一个简单的服务器端和客户端程序,通过本地主机进行通信。

2. 数据传输与流量控制在TCP连接建立后,我们进行了数据的传输实验。

首先,我们发送了一个较小的数据包,观察到数据包的传输过程中,TCP协议会自动进行流量控制,确保数据的可靠传输。

接着,我们发送了一个较大的数据包,发现TCP会将大数据包拆分成多个小数据包进行传输,并在接收端进行重组。

3. 拥塞控制为了模拟网络拥塞的情况,我们在实验中人为地降低了网络带宽。

通过Wireshark抓包分析,我们观察到TCP协议在发现网络拥塞时,会自动减少发送速率,以避免网络的过载。

同时,我们还注意到TCP协议会根据网络的状况动态调整拥塞窗口的大小,以提高网络的利用率。

4. 可靠性与重传机制为了测试TCP协议的可靠性,我们在实验中故意模拟了数据包丢失的情况。

通过Wireshark的分析,我们发现当发送端未收到确认消息时,会自动触发重传机制,确保数据的可靠传输。

同时,TCP还会根据超时时间的动态调整,以适应不同网络环境下的传输速度。

五、实验总结通过本次实验,我们深入了解了TCP协议的工作原理和特点。

TCP作为一种可靠的传输协议,在互联网通信中发挥着重要的作用。

它通过流量控制、拥塞控制和重传机制等手段,确保了数据的可靠传输,并适应了不同网络环境的变化。

在今后的学习和实践中,我们将进一步深入研究TCP协议的细节,并结合实际应用场景,优化网络通信的性能和可靠性。

计算机网络课程设计IP数据包解析(共5篇)

计算机网络课程设计IP数据包解析(共5篇)

计算机网络课程设计IP数据包解析(共5篇)第一篇:计算机网络课程设计 IP数据包解析课设名称:IP数据包解析班级:学号:姓名:指导老师:日期: 2012.6.15计算机网络课程设计报告目录1.课程设计目的 (1)2.课程设计要求 (1)3.程序设计分析 (1)3.1 网卡设置 (1)3.2 使用套接字 (2)3.2.2 接收数据包 (2)3.3 定义IP头部的数据结构 (3)3.4 IP包的解析 (3)3.5 协议的定义 (4)3.6捕获处理 (4)4.运行结果 (5)5.总结 (5)6.源程序代码 (6)Ip数据包解析1.课程设计目的本课程设计的目的就是设计一个捕获并解析IP数据包的程序,并根据这个程序,说明IP数据包的结构及IP协议的相关问题,从而对IP 层的工作原理有更好的理解和认识。

2.课程设计要求本设计的目标是捕获网络中的IP数据包,解析数据包的内容,将结果显示在标准输出上,并同时写入日志文件。

程序的具体要求如下:1)以命令行形式运行:ipparse logfile,其中ipparse是程序名, 而logfile则代表记录结果的日志文件。

2)在标准输出和日志文件中写入捕获的IP包的版本、头长度、服务类型、数据包总长度、数据包标识、分段标志、分段偏移值、生存时间、上层协议类型、头校验和、源IP地址和目的IP地址等内容。

3)当程序接收到键盘输入Ctrl+C时退出3.程序设计分析3.1 网卡设置为了获取网络中的IP数据包,必须对网卡进行编程,在这里使用套接字(socket)进行编程。

但是,在通常情况下,网络通信的套接字程序只能响应与自己硬件地址相匹配的数据包或是以广播形式发出的数据包。

对于其他形式的数据包,如已到达网络接口,但却不是发送到此地址的数据包,网络接口在骓投递地Ip数据包解析址并非自身地址之后将不引起响应,也就是说应用程序无法收取与自己无关的数据包。

我们要想获取网络设备的所有数据包,就是需要将网卡设置为混杂模式。

tcp网络编程课程设计

tcp网络编程课程设计

tcp网络编程课程设计一、课程目标知识目标:1. 让学生理解TCP协议的基本原理,掌握TCP网络编程的基本概念和技术要点。

2. 使学生掌握套接字编程的基本方法,能够运用所学知识构建简单的TCP客户端和服务器端程序。

3. 帮助学生了解网络编程中的异常处理和资源管理,培养良好的编程习惯。

技能目标:1. 培养学生运用所学知识解决实际问题的能力,能够独立设计和实现简单的TCP网络应用程序。

2. 提高学生的编程实践能力,使其在编程过程中熟练运用调试工具,排查并解决常见问题。

3. 培养学生团队协作能力,能够与他人共同分析和讨论网络编程问题,共同完成项目任务。

情感态度价值观目标:1. 激发学生对计算机网络编程的兴趣,培养其主动探索和学习的积极性。

2. 培养学生严谨、认真、负责的学术态度,使其在网络编程过程中遵循相关规范和道德准则。

3. 增强学生的网络安全意识,使其在编程过程中注重保护用户隐私和数据安全。

课程性质:本课程为实践性较强的学科,注重培养学生的动手能力和实际应用能力。

学生特点:学生已具备一定的编程基础和网络知识,具有较强的学习能力和探究精神。

教学要求:教师需结合实际案例,引导学生掌握TCP网络编程的基本原理和技能,注重培养学生的实践能力和团队协作能力。

在教学过程中,关注学生的个体差异,因材施教,确保每位学生都能达到课程目标。

通过课后作业、项目实践和课堂讨论等多种形式,评估学生的学习成果。

二、教学内容1. TCP协议基本原理:讲解TCP协议的特点、三次握手和四次挥手过程,引导学生理解可靠传输和流量控制的重要性。

教材章节:第一章TCP/IP协议基础2. 套接字编程:介绍套接字的概念、类型和编程接口,教授如何使用套接字进行客户端和服务器端通信。

教材章节:第二章套接字编程基础3. 简单的TCP客户端和服务器端程序设计:讲解如何构建TCP客户端和服务器端程序,分析常见的编程模型和代码结构。

教材章节:第三章TCP网络编程实例4. 异常处理与资源管理:教授在网络编程过程中如何进行异常处理和资源管理,提高程序的稳定性和可靠性。

tcpip网络编程课程设计

tcpip网络编程课程设计

tcp ip网络编程课程设计一、课程目标知识目标:1. 理解TCP/IP网络编程的基本概念和原理,掌握网络编程中常用的数据结构和协议;2. 学会使用套接字(Socket)进行网络编程,掌握TCP和UDP协议下的客户端和服务器端编程方法;3. 了解网络编程中的异常处理和多线程技术,提高网络应用程序的稳定性和性能。

技能目标:1. 能够独立编写简单的TCP客户端和服务器端程序,实现数据的传输和接收;2. 能够独立编写简单的UDP客户端和服务器端程序,实现数据的发送和接收;3. 能够运用所学知识解决实际网络编程问题,具备一定的网络编程调试能力。

情感态度价值观目标:1. 培养学生对网络编程的兴趣,激发学习主动性和创新意识;2. 培养学生的团队协作能力,提高沟通表达和问题解决能力;3. 引导学生认识到网络编程在现代社会中的重要地位,培养社会责任感和使命感。

课程性质:本课程为实践性较强的课程,要求学生在理解网络编程基本原理的基础上,动手实践,培养实际编程能力。

学生特点:学生具备一定的编程基础,对网络编程有一定了解,但实际操作经验不足。

教学要求:教师应注重理论与实践相结合,引导学生通过实际操作掌握网络编程技术,关注学生的学习过程,提高学生的实践能力。

在教学过程中,将目标分解为具体的学习成果,便于后续教学设计和评估。

二、教学内容1. TCP/IP网络编程基本概念:网络编程概念、TCP/IP协议栈、IP地址和端口号;2. 套接字编程基础:套接字概念、套接字类型、套接字编程流程;3. TCP网络编程:TCP协议原理、TCP客户端和服务器端编程、数据传输和接收、多线程服务器端实现;4. UDP网络编程:UDP协议原理、UDP客户端和服务器端编程、数据发送和接收、UDP编程中的异常处理;5. 网络编程进阶:网络编程中的多线程和并发、网络通信安全、网络编程调试技巧。

教学内容安排和进度:第一周:介绍网络编程基本概念,学习TCP/IP协议栈,理解IP地址和端口号;第二周:学习套接字编程基础,动手实践简单的TCP客户端和服务器端程序;第三周:深入学习TCP网络编程,编写多线程服务器端程序,实现数据传输和接收;第四周:学习UDP网络编程,编写UDP客户端和服务器端程序,了解异常处理;第五周:进行网络编程进阶学习,了解多线程和并发,学习网络通信安全及调试技巧。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

目录一、软件概要简介 (6)二、概要设计 (6)1 62类图 (6)3.数据结构的定义 (6)4.程序截图 (7)三、详细设计 (8)1关键性代码 (8)1.1内存映射文件读 (9)1.2内存映射文件写 (9)1.3文件的发送 (9)1.4文件的接收 (9)1.4.1客户端接收套接字 (9)1.4.2 客户端把接收到的文件写人自己的文件..10四、调试分析及测试结果 (15)一、软件概要简介我们做的是基于tcp数据包发送和接收的文件传输,采用的是客户/服务器模式,首先客户端连接到服务器,然后服务器端就可以选择需要传输的文件,开始传输。

二、概要设计11.1内存映射文件我们首先是用内存映射文件的方法把文件一块一块的从磁盘映射到内存,每映射一块,就传输一块,直到把整个文件都传输完毕为止。

内存映射文件内存映射文件与虚拟内存有些类似,通过内存映射文件可以保留一个地址空间的区域,同时将物理存储器提交给此区域,只是内存文件映射的物理存储器来自一个已经存在于磁盘上的文件,而非系统的页文件,而且在对该文件进行操作之前必须首先对文件进行映射,就如同将整个文件从磁盘加载到内存。

由此可以看出,使用内存映射文件处理存储于磁盘上的文件时,将不必再对文件执行I/O操作,这意味着在对文件进行处理时将不必再为文件申请并分配缓存,所有的文件缓存操作均由系统直接管理,由于取消了将文件数据加载到内存、数据从内存到文件的回写以及释放内存块等步骤,使得内存映射文件在处理大数据量的文件时能起到相当重要的作用。

另外,实际工程中的系统往往需要在多个进程之间共享数据,如果数据量小,处理方法是灵活多变的,如果共享数据容量巨大,那么就需要借助于内存映射文件来进行。

实际上,内存映射文件正是解决本地多个进程间数据共享的最有效方法。

内存映射文件并不是简单的文件I/O操作,实际用到了Windows的核心编程技术--内存管理。

所以,如果想对内存映射文件有更深刻的认识,必须对Windows操作系统的内存管理机制有清楚的认识,内存管理的相关知识非常复杂,超出了本文的讨论范畴,在此就不再赘述,感兴趣的读者可以参阅其他相关书籍。

下面给出使用内存映射文件的一般方法:首先要通过CreateFile()函数来创建或打开一个文件内核对象,这个对象标识了磁盘上将要用作内存映射文件的文件。

在用CreateFile()将文件映像在物理存储器的位置通告给操作系统后,只指定了映像文件的路径,映像的长度还没有指定。

为了指定文件映射对象需要多大的物理存储空间还需要通过CreateFileMapping()函数来创建一个文件映射内核对象以告诉系统文件的尺寸以及访问文件的方式。

在创建了文件映射对象后,还必须为文件数据保留一个地址空间区域,并把文件数据作为映射到该区域的物理存储器进行提交。

由MapViewOfFile()函数负责通过系统的管理而将文件映射对象的全部或部分映射到进程地址空间。

此时,对内存映射文件的使用和处理同通常加载到内存中的文件数据的处理方式基本一样,在完成了对内存映射文件的使用时,还要通过一系列的操作完成对其的清除和使用过资源的释放。

这部分相对比较简单,可以通过UnmapViewOfFile()完成从进程的地址空间撤消文件数据的映像、通过CloseHandle()关闭前面创建的文件映射对象和文件对象。

1.2基于socket的tcp数据包的接收和发送Tcp的Socket编程的步骤基本就是这样:首先客户端请求连接服务器,服务器接受连接,服务器记住客户端的ip地址之后就可以进行通信了。

2类图首先我们用的是高度的抽象类,对于每一个模块功能,我们都设计了一个抽象类,因为服务器跟客户端的功能其实差不多,稍微有些不同而已,所以我们用抽象类来派生子类,在子类中具体实现某些函数的功能,节省了许多代码,提高了复用,并且程序扩展性得到了增强。

Model类主要负责文件传输,基于socket 的tcp数据包的接收和发送都是在这个类里面。

Filemodel类主要负责文件的读写,也就是用内存映射文件的方法去读写内存都是在这里实现的。

Control类主要是MFC窗口信息的控制用的,包括实时更新传输进度等。

还有些类没有画上来,因为比较简单吧,大概说下用途类的名称: CFormat* 基本用途: 定义格式化相关数据信息为字符串形式的接口类的名称: CConfigFile* 基本用途: 定义配置文件的基本操作,供上层的组件调用类的名称: CTray* 基本用途: 定义应用程序托盘操作类的相关属性和方法,为高层组件提供统一的调用接类的名称: CValidJudge* 基本用途: 提供数字配置信息合法性判断的统一接口口3.数据结构的定义/**********************通信消息结构定义*************************************/ typedef enum{/********************server端发送的消息类型定义*************************/ SEND_FILE_INFO_REQ = (WM_USER + 1), //发送文件信息请求SEND_FILE_REQ = (WM_USER + 2), //发送文件请求/********************client端发送的消息类型定义*************************/ RECV_FILE_INFO_ACK = (WM_USER + 3), //接收文件信息成功RECV_FILE_ACK = (WM_USER + 4), //接收文件块成功/********************公用消息定义***************************************/ INTERRUPT_TRANSFER = (WM_USER + 5), //中断传输CLOSE_CONNECT = (WM_USER + 6), //关闭连接/********************模型向视图通信消息定义*****************************/ CONNECT_SUCCESS = (WM_USER + 7), //连接成功TRANSFERRING_FILE = (WM_USER + 8), //传输文件TRANSFER_OVER = (WM_USER + 9), //传输正常结束}MessageType;/************************文件信息结构定义***********************************/ typedef struct{char _name[MAX_FILE_PATH_LEN]; //文件名//long _fileSize; //文件大小//DWORD _size;Size _fileSize; //文件大小}FileInfo;/**************************传输所用的数据结构定义***************************/ typedef struct{BYTE _buf[BLOCK_SIZE]; //发送的文件块内容int _len; //分块的长度//long _offset; //文件内容偏移值//DWORD _offSet; //文件内容偏移值Size _offset; //文件内容偏移值}TransferData;/**********************server给client发送的消息的数据部分的定义*************/ typedef union{FileInfo _fileInfo; //文件信息,第一次传输所发送的内容TransferData _transferData; //传输数据}DataFromServer;4.程序截图三详细设计11.1内存映射文件读/*---------------------------------------------------------------------------* 函数名称: Read* 函数功能: 从指定路径文件读取指定偏移处的指定大小的文件块* 入口参数: CString _strFilePath, 文件路径;Size _fileSize, 文件大小void *_buf, 文件读取缓冲区Size _offset, 读取的偏移处DWORD _size, 指定的读取的内容大小* 出口参数: 正确返回实际读取的长度, 否则返回READ_ERROR---------------------------------------------------------------------------*/DWORD CFileModel::Read(CString _strFilePath, Size _fileSize, void *_buf, Size _offset, DWORD _size){HANDLE hFile = CreateFile(_strFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (hFile == INV ALID_HANDLE_V ALUE){TRACE("CreateFile Fail, File Path : %s, Error Code : %d \n", _strFilePath, GetLastError());return READ_ERROR;}LARGE_INTEGER _li;_li.QuadPart = _fileSize;HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONL Y, (DWORD)(_li.HighPart), (DWORD)(_li.LowPart), NULL);if (hFileMap == INV ALID_HANDLE_V ALUE){TRACE("CreateFileMapping Fail, File Path : %s, Error Code : %d \n", _strFilePath, GetLastError());return READ_ERROR;}CloseHandle(hFile);_li.QuadPart = _offset;LPBYTE lpFile = (LPBYTE)MapViewOfFile(hFileMap, FILE_MAP_READ, (DWORD)(_li.HighPart), (DWORD)(_li.LowPart), _size);//_offset >> 32 _offset & 0xFFFFFFFFif (lpFile == NULL)TRACE("MapViewOfFile Fail, File Path : %s, Error Code : %d \n", _strFilePath, GetLastError());CloseHandle(hFileMap);return READ_ERROR;}memcpy(_buf, lpFile, _size);UnmapViewOfFile(lpFile);CloseHandle(hFileMap);return _size;}1.2 内存映射文件写/*---------------------------------------------------------------------------* 函数名称: Write* 函数功能: 将缓冲区内容写入指定路径的文件的指定偏移位置处* 入口参数: CString _strFilePath, 文件路径;Size _fileSize, 文件大小void *_buf, 需要保存内容的缓冲区Size _offset, 写入的偏移处DWORD _size, 指定的写入的内容大小* 出口参数: 正确返回实际写入的内容的大小; 否则返回FALSE---------------------------------------------------------------------------*/DWORD CFileModel::Write(CString _strFilePath, Size _fileSize, const void *_buf, Size _offset, DWORD _size){HANDLE hFile = CreateFile(_strFilePath, GENERIC_WRITE|GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);if (hFile == INV ALID_HANDLE_V ALUE){TRACE("CreateFile Fail, File Path : %s, Error Code : %d \n", _strFilePath, GetLastError());return WRITE_ERROR;}LARGE_INTEGER _li;_li.QuadPart = _fileSize;HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, (DWORD)(_li.HighPart), (DWORD)(_li.LowPart), NULL);if (hFileMap == INVALID_HANDLE_V ALUE)TRACE("CreateFileMapping Fail, File Path : %s, Error Code : %d \n", _strFilePath, GetLastError());return WRITE_ERROR;}CloseHandle(hFile);_li.QuadPart = _offset;LPBYTE lpFile = (LPBYTE)MapViewOfFile(hFileMap, FILE_MAP_WRITE, (DWORD)(_li.HighPart), (DWORD)(_li.LowPart), _size);if (lpFile == NULL){TRACE("MapViewOfFile Fail, File Path : %s, Error Code : %d \n", _strFilePath, GetLastError());CloseHandle(hFileMap);return WRITE_ERROR;}memcpy(lpFile, _buf, _size);UnmapViewOfFile(lpFile);CloseHandle(hFileMap);return _size;}1.3 文件的发送/*---------------------------------------------------------------------------* 函数名称: TransferProcess* 函数功能: 实现文件传输的接口,对于Server来说,用于实现发送文件的功能* 入口参数: 无* 出口参数: 无* 更新原因: 设置读文件大小的控制逻辑; 调整文件模型的使用接口---------------------------------------------------------------------------*/void CServerModel::TransferProcess(){InitializeCriticalSection(&g_csTransfer);if ( (_offset < _fileInfo._fileSize) && (_fileInfo._fileSize > 0) ){if (_state != TRANSFERRING){AfxEndThread(0);}DWORD _size;if (_offset + BLOCK_SIZE > _fileInfo._fileSize){_size = (DWORD)(_fileInfo._fileSize - _offset);}else{_size = BLOCK_SIZE;}/************************************************************************** */Message _msg;memset(&_msg, 0, sizeof(Message));//CFileModel * _fileModel;//_fileModel = new CFileReadModel(_strFilePath, _fileInfo._fileSize);//读取一块文件, 为提高效率, 此处直接采用静态APIEnterCriticalSection(&g_csTransfer);//_size = _fileModel->Serialize(_msg._messageFromServer._data._transferData._buf, _offset, _size);_size = CFileModel::Read(_strFilePath, _fileInfo._fileSize, _msg._messageFromServer._data._transferData._buf, _offset, _size);LeaveCriticalSection(&g_csTransfer);//delete _fileModel;//_fileModel = NULL;if (_size == READ_ERROR){AfxMessageBox("读文件出错!");InterruptTransfer();AfxEndThread(0);}_msg._messageFromServer._messageType = SEND_FILE_REQ;_msg._messageFromServer._data._transferData._len = _size;_msg._messageFromServer._data._transferData._offset = _offset;//设置待发送的消息的内容if (Send(_msg) == SOCKET_ERROR) //发送一块文件{AfxMessageBox("发送文件出错!");InterruptTransfer();AfxEndThread(0);}EnterCriticalSection(&g_csTransfer);_offset = _offset + _size; //更新进度LeaveCriticalSection(&g_csTransfer);if (_offset >= _fileInfo._fileSize){TransferOver(); //发送完毕AfxEndThread(0);}::SendMessage(m_hWnd, TRANSFERRING_FILE, 0, 0); //发送完一块文件后提示更新视图}}1.4 文件的接收1.4.1客户端接收套接字/*---------------------------------------------------------------------------* 函数名称: MessageProcess* 函数功能: 消息处理过程,此处控制消息处理的流程* 入口参数: 无* 出口参数: 无---------------------------------------------------------------------------*/void CModel::MessageProcess(){InitializeCriticalSection(&g_csMessage);while (TRUE){if (_state == INIT) //断开连接后,关闭消息监听线程{AfxEndThread(0);}else{EnterCriticalSection(&g_csMessage);int _length = recv(_connectedSock, (char *)(&_buffer), sizeof(Message), 0);LeaveCriticalSection(&g_csMessage);if (_length != SOCKET_ERROR){//message handleHandle();}else{Sleep(1);}}}}1.4.2 客户端把接收到的文件写人自己的文件/*---------------------------------------------------------------------------* 函数名称: TransferProcess* 函数功能: 实现具体的文件接收过程* 入口参数: 无* 出口参数: 无* 更新原因: 调整文件模型的使用接口---------------------------------------------------------------------------*/void CClientModel::TransferProcess(){InitializeCriticalSection(&g_csTransfer);if ( (_offset < _fileInfo._fileSize) && (_fileInfo._fileSize > 0) ){if (_state != TRANSFERRING){AfxEndThread(0);}DWORD _size = _buffer._messageFromServer._data._transferData._len;Size _fileSize = _offset + _size; //递增式写入,保证能正确读取断点续传的位置//CFileModel * _fileModel = new CFileWriteModel(_strFilePath, _fileSize);//写一块文件,为提高效率,此处直接采用静态APIEnterCriticalSection(&g_csTransfer);//_size = _fileModel->Serialize(_buffer._messageFromServer._data._transferData._buf, _offset, _size);_size = CFileModel::Write(_strFilePath, _fileSize, _buffer._messageFromServer._data._transferData._buf, _offset, _size);LeaveCriticalSection(&g_csTransfer);//delete _fileModel;//_fileModel = NULL;if (_size != WRITE_ERROR){EnterCriticalSection(&g_csTransfer);_offset = _offset + _size;LeaveCriticalSection(&g_csTransfer);if (_offset >= _fileInfo._fileSize) //接收到文件的最后一块不需要发送确认信息{TransferOver();AfxEndThread(0);}}Message _msg;memset(&_msg, 0, sizeof(Message));_msg._messageFromClient._message = RECV_FILE_ACK;_msg._messageFromClient._offset = _offset;if (Send(_msg) == SOCKET_ERROR){InterruptTransfer();AfxEndThread(0);}::SendMessage(m_hWnd, TRANSFERRING_FILE, 0, 0);}}四、调试分析及测试结果。

相关文档
最新文档