文件传输程序设计

大学生网络协议分析课实验:文件传输程序设计 网络协议分析课实验:文件传输程序设计 要求: 设计一个控制台应用程序,基于流式套接字完成文件传输的功能。具体功能如下: 1.将任意类型的文件从客户端传送到服务器,传送前提示用户输入完整的文件名(含路径和扩展名); 2.必须可以传送大文件(50MB以上,大文件不用发给我,我自己找文件测试); 3.必须有文件传送进度提示。 4. 程序完成后,删除Debug,ipch文件夹,以及sdf,suo,opensdf等中间文件。 然后压缩,压缩文件命名为311700099... 阅读详情

一个简单的文件传输程序

文件是一种数据存储的形式,因此文件的传输实质上就是数据的传输。在这个程序中主要步骤为
1.发送方(这里暂定为服务端)首先打开文件将文件数据读入应用程序的发送缓冲区,然后调用send()函数发送给接收方(这里暂定为客户端)。
2.接收方调用recv()函数接收数据,并将接收到的数据写入文件.

程序中会用到的一些技术

1.文件位置的表示

在C/C++程序中,文件路径通常是一个由盘符、文件夹名、子文件夹名和文件名组成的字符串,各项之间用反斜线"“隔开。
比如 D:\C++程序\test\readme.txt 在程序代码中的文件路径应该表示成如下形式:
D:\C++程序\test\readme.txt
但是程序在运行时键盘输入的文件路径仍然是正常表示,即反斜线仍是其自身”"。
2.C++中的文件操作
①:C++中的文件处理功能是由输入文件流ifstream和输出文件流ofstream提供的,这两个流在头文件fstream中定义。
②:文件操作基本步骤
Ⅰ:在程序中包含头文件fstream
#include “fstream”
Ⅱ:定义文件流变量
ifstream inFile; //定义输入文件流对象
ofstream outFile; //定义输出文件流对象
Ⅲ:打开文件
inFile.open( filename, inmode);
outFile.open( filename, outmode);
inFile和outFile是第②中定义的流对象,filename是要打开的文件名,可以包含文件路径,inmode和outmode则是打开或建立文件的方式,该参数有默认值,可缺省。
Ⅳ:读写文件
对二进制文件使用get()方法可以从输入流中读取一个字符,put()方法则用于向输出流中写入一个字节
char ch1,ch2=’A’; //定义两个字符变量
inFile.get(ch1); //从输入文件流中读取一个字符存入变量ch1;
outFile.put(ch2); //将变量ch2种的一个字符写入输出文件流;
Ⅴ:关闭文件
inFile.close();
outFile.close();
3.获取文件长度的方法
接收端判断文件传输是否结束需要使用文件长度,但C/C++并不提供直接获取文件长度的函数。有很多方法可以获取文件长度,这里只介绍一种常用的简单方法。
这种方法的原理是基于这样一个事实,就是当文件的读写位置指针位于文件结束时,其值就等于文件长度。具体实现方法参见如下函数getfilesize()
long getfilesize(const char * filename)
{
ifstream inFile(filename); //定义流变量并打开文件
inFile.seekg(0, ios::end); //设置文件指针到文件流的尾部
streampos ps = inFile.tellg(); //读取文件指针的位置
inFile.close(); //关闭文件流
return ps;
}
4.文件信息结构体定义
发送文件名和文件长度所用的结构
struct fileMessage {
char fileName[256];
long int fileSize;
};
5.文件传输程序发送端和接收端的完整工作流程
文件传输流程

服务器端程序代码:

// Server.cpp : Defines the entry point for the console application.
//

#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <fstream>
#include <WinSock2.h>
using namespace std;

#pragma comment(lib, "Ws2_32.lib")
#define  PORT 1024

typedef struct fileMessage
{
	char fileName[26];
	long int filesize;
}fileMessage;


int main()
{
	SOCKET sock_server, newsock;
	struct sockaddr_in server_addr, client_addr; 
	char msg[] = { "Hello clinet" };
	// 初始化 winsock2.dll[12/27/2017 MagicScaring]
	WSADATA wsaData;
	WORD wVersionRequested = MAKEWORD(2, 2);		//生成版本号
	if (WSAStartup(wVersionRequested, &wsaData) != 0)
	{
		cout << "加载 winsock.dll失败" << endl;
		return 0;
	}
	// 创建套接字 [12/27/2017 MagicScaring]
	if ((sock_server = socket(AF_INET, SOCK_STREAM, 0)) == SOCKET_ERROR)
	{
		cout << "创建套接字失败! 错误代码:" << WSAGetLastError() << endl;
		WSACleanup();					//注销WinSock动态链接库
		return 0;
	}
	// 填写需要绑定的本地地址 [12/27/2017 MagicScaring]
	int addr_len = sizeof(struct sockaddr_in);
	memset((void*)&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(PORT);
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	//server_addr.sin_addr.s_addr = inet_addr("192.168.5.38");

	if (bind(sock_server, (struct sockaddr*)&server_addr, addr_len) != 0)
	{
		cout << "绑定失败!错误代码:" << WSAGetLastError() << endl;
		closesocket(sock_server);				//关闭已连接套接字
		WSACleanup();							//注销WinSock动态链接库
		return 0;
	}

	// 开始监听 [12/27/2017 MagicScaring]
	if (listen(sock_server, 0) != 0)
	{
		cout << "listen调用失败!错误代码:" << WSAGetLastError() << endl;
		closesocket(sock_server);
		WSACleanup();
		return 0;
	}
	else
	{
		cout << "listening...." << endl;
	}
	// 开始发送文件 [1/2/2018 MagicScaring]
	char filename[500];
	cout << "请输入要传输的文件的路径" << endl;
	cin.getline(filename, 500);
	// 接收客户端连接请求 [1/2/2018 MagicScaring]
	if ((newsock = accept(sock_server, (struct sockaddr *)&client_addr, &addr_len)) == INVALID_SOCKET)
	{
		cout << "accept 函数调用失败! 错误代码:" << WSAGetLastError() << endl;
		closesocket(sock_server);
		WSACleanup();
		return 0;
	}
	cout << "connect from " << inet_ntoa(client_addr.sin_addr) << endl;

	char OK[3], fileBuffer[1000];
	fileMessage fileMsg;
	int size = strlen(filename);
	
	
	while (filename[size] != '\\' && size > 0)
	{
		size--;
	}
	strcpy(fileMsg.fileName, filename + size + 1);

	ifstream inFile(filename, ios::in | ios::binary);

	if (!inFile.is_open())
	{
		cout << "Can not open " << filename << endl;
		closesocket(newsock);
		WSACleanup();
		return 0;
	}
	// 获取文件长度 [1/2/2018 MagicScaring]
	inFile.seekg(0, ios::end);
	size = inFile.tellg();
	inFile.seekg(0, ios::beg);
	
	fileMsg.filesize = htonl(size);
	send(newsock, (char*)&fileMsg, sizeof(fileMsg), 0);

	// 接收客户端发送来的OK信息 [1/2/2018 MagicScaring]
	if (recv(newsock, OK, sizeof(OK), 0) <= 0)
	{
		cout << "接收OK信息失败,程序退出" << endl;
		closesocket(sock_server);
		closesocket(newsock);
		WSACleanup();
		return 0;
	}
	// 发送文件内容 [1/2/2018 MagicScaring]
	if (strcmp(OK, "OK") == 0)
	{
		while (!inFile.eof())
		{
			inFile.read(fileBuffer, sizeof(fileBuffer));
			size = inFile.gcount();		//获取实际读取的字节数
			send(newsock, fileBuffer, size, 0);
		}
		cout << "file transfer finished" << endl;
		inFile.close();
	}
	else
	{
		cout << "对方无法接收文件" << endl;
	}

	closesocket(sock_server);
	closesocket(newsock);
	WSACleanup();
    return system("pause");
}


客户端程序代码:

// Client.cpp : Defines the entry point for the console application.
//

#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <fstream>
#include <WinSock2.h>
using namespace std;

#pragma comment(lib, "Ws2_32.lib")
#define  PORT 1024

typedef struct fileMessage
{
	char fileName[26];
	long int filesize;
}fileMessage;
#define  PORT 1024


int main()
{
	SOCKET sock_client;
	struct sockaddr_in server_addr, client_addr;
	int addr_len = sizeof(struct sockaddr_in);
	int name_len;
	char msgbuffer[1000];
	memset(msgbuffer, 0, sizeof(msgbuffer));
	// 初始化 winsock2.dll[12/27/2017 MagicScaring]
	WSADATA wsaData;
	WORD wVersionRequested = MAKEWORD(2, 2);		//生成版本号
	if (WSAStartup(wVersionRequested, &wsaData) != 0)
	{
		cout << "加载 winsock.dll失败" << endl;
		return 0;
	}
	// 创建套接字 [12/27/2017 MagicScaring]
	if ((sock_client = socket(AF_INET, SOCK_STREAM, 0)) == SOCKET_ERROR)
	{
		cout << "创建套接字失败! 错误代码:" << WSAGetLastError() << endl;
		WSACleanup();					//注销WinSock动态链接库
		return 0;
	}
	// 填写服务器地址 [12/27/2017 MagicScaring]
	char IP[20] = { "192.168.5.38" };
	/*char IP[20];
	cout << "输入服务器地址:" << endl;
	cin >> IP;*/
	memset((void*)&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(PORT);
	server_addr.sin_addr.s_addr = inet_addr(IP);

	// 与服务器建立连接 [12/27/2017 MagicScaring]
	if (connect(sock_client, (struct sockaddr*)&server_addr, addr_len) == SOCKET_ERROR)
	{
		cout << "连接失败! 错误代码:" << WSAGetLastError() << endl;
		closesocket(sock_client);
		WSACleanup();
		return 0;
	}
	fileMessage fileMsg;
	long int filelen = 0;
	char fileName[500] = "C:\\Users\\MagicScaring\\Desktop\\";
	char ok[3] = "OK";
	char fileBuffer[1000];
	_mkdir(fileName);

	if ((filelen = recv(sock_client, (char*)&fileMsg, sizeof(fileMsg), 0)) <= 0)
	{
		cout << "未接受到文件名字及文件长度" << endl;
		closesocket(sock_client);
		WSACleanup();
		return 0;
	}
	filelen = ntohl(fileMsg.filesize);
	strcat(fileName, fileMsg.fileName);
	
	// 创建文件准备接收文件内容 [1/2/2018 MagicScaring]

	ofstream outFile(fileName, ios::out | ios::binary);
	if (!outFile.is_open())
	{
		cout << "Cannot open " << fileName << endl;
		closesocket(sock_client);
		WSACleanup();
		return 0;
	}
	send(sock_client, ok, sizeof(ok), 0);

	// 接收文件数据并写入文件 [1/2/2018 MagicScaring]
	int size = 0;
	do 
	{
		size = recv(sock_client, fileBuffer, sizeof(fileBuffer), 0);
		outFile.write(fileBuffer, size);
		filelen -= size;
	} while (size != 0 && filelen > 0);

	cout << "Transfer finished" << endl;
	outFile.close();
	closesocket(sock_client);
	WSACleanup();
	
    return system("pause");
}


结果演示:

服务端
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CPe80uY9-1592977402618)(https://img-blog.youkuaiyun.com/20180103111243226?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTWFnaWNTY2FyaW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)]

基于C++的高效文件传输程序设计与实现 在网络传输中,常出现多个模块共享同一块数据副本的情况(如:读线程 → 加密模块 → 发送队列)。若每次都深拷贝,将严重消耗CPU与内存带宽。解决方案是使用或配合自定义删除器,实现引用计数式共享与自动释放。return vec;// 多个线程可安全持有buffer引用优势说明- 多个transmit()调用可共享同一份数据;- 当最后一个引用释放时,自动析构vector,无需手动管理;- 结合内存池可进一步减少分配开销。 阅读详情

相关推荐

基于VB的串口文件传输程序设计与实现

分包算法需满足两个关键条件:所有中间包长度一致,便于接收端预测;最后一包允许短于标准长度,且标记为“结束包”。DoEventsNext iEnd Sub为使接收端能准确识别每一帧数据,必须定义统一的数据包格式。这类似于网络通信中的“帧结构”,包含同步字段、元信息与校验机制。字符名称十六进制十进制含义ENQ0x055请求通信(Enquiry)ACK0x066确认应答NAK0x1521否定应答。

weixin_35671843的博客 579

LINUX 网络编程实验课题-基于TCP/IP协议编写简易聊天软件,不支持高并发

// FileDownloadThroughServer.cpp : Defines the entry point for the console application. /*---------------------------------------------------------------------------------------------------------- 功能: 建立C/S结构的文件下载系统。每个客户端可以提供不定数目的文件用于共享,也可以下载别人共享出来的文件...

m0_59612452的博客 454

网络程序设计-基于UDP的文件传输

网络程序设计-基于UDP的文件传输,广西科技大学。

C++_文件传输1_发送与接收

Linux下基于TCP的文件传输 相关函数及结构体:int open(char *path,intflag,/*mode_t mode*/); open建立了一条到文件的访问路径,如果调用成功则会返回一个能够被read,write和其它系统调用的文件描述符,它不会与任何其它运行中的进程共享,flag(O_RDONLY(只读),O_WRONLY(只写),O_RDWR(读写)...

Duc_Duke的博客 1300

算法基础之数组双指针(Leetcode题型归纳)

数组双指针(Leetcode题型归纳)1.前言2.双指针基础3.相向双指针3.1定义3.2真题分析3.2.1两数之和(1)3.2.2两数之和-输入有序数组(167)3.2.3三数之和(15)3.2.4最接近的三数之和(16)3.2.5四数之和(18)3.2.6盛最多水的容器(11)3.2.7有效三角形的个数(611)4.同向双指针-快慢指针4.1定义4.2真题分析4.1.1删除排序数组中的重复项(26)4.1.2移除元素(27)4.1.3删除排序数组中的重复项(80)4.1.4移动零(283)4.1.5数组

Buluchacha的博客 1034

解决Windows 10安装语言包时遇到的0x800F0954错误

在安装Windows 10操作系统的语言包时,如果遇到错误代码0x800F0954的提示,这无疑会让许多用户感到困惑和无助。这个错误通常意味着在安装过程中遇到了一些阻碍,导致无法正常完成语言包的安装。本文将为大家详细解析这个错误代码0x800F0954,并提供一系列有效的解决方法,帮助大家顺利安装所需的语言包。

nntxthml的博客 3793

嵌入式项目实战:socket通信模拟服务器客户端实现文件传送(基于c++语言)

在Socket服务端,能够读出一副图像数据,经过网络通信,自己设计协议,将这副图片发送到客户端,客户端接收到这副图片后,将其显示在屏幕上。

weixin_44107140的博客 2689

SAP 批量处理分包事后调整:BAPI_GOODSMVT_CREATE 关键参数与避坑指南

本文详细解析了SAP系统中使用BAPI_GOODSMVT_CREATE进行分包事后批量调整的关键参数配置与常见错误排查。重点介绍了GOODSMVT_CODE设置为'07'的必要性、GOODSMVT_ITEM结构体的正确配置方法,以及如何避免M7384、M7386等常见错误,帮助用户高效处理分包业务中的数量调整问题。

weixin_29276847的博客 566

C++实现通过UDP传输文件

一. 程序说明 1.本程序通过 UDP 来传输文件及其管理元数据(文件名、大小和日期等),包括client.cpp和server.cpp,分别是客户端程序和服务端程序。 2.文件以二进制形式传输。 3.由客户端指定文件目录,将文件传送到服务端,除了文件名之外,附带传送文件大小、创建时间等信息。 4.获取文件大小和创建日期的详细程序可以看C++获取文件的创建时间和大小 5.客户端发送完毕后,向服务端...

Jundesky的博客 9036

TwinCAT3 Modbus-TCP Client/Server使用

/起始地址是12289//起始地址是12294。

panjinliang066333的博客 7732

无人机散热系统设计:从材料选择到智能调控的全面解析

本文全面解析无人机散热系统设计,从材料选择到智能调控,探讨了导热界面材料、轻量化散热结构和智能调控算法的应用。通过实战案例,展示了如何在极端环境下优化散热性能,提升无人机的工作效率和可靠性。

weixin_42567279的博客 429

网络文件传输程序设计(上)

前几节课学习了TCP套接字(socket),能实现字符串的发送和接收功能,简单地做到了客户机和服务器的对话。我们继续学习TCP套接字,利用它的字节传输技术,实现网络文件传输。一个端口用来对话,传递控制信息,总是开启一个端口实现文件数据传递服务,有数据传输服务时开启网络对话和网络文件传输,使用TCP的socket编程,本质还是一样,对话过程,使用字符流来包装;而网络文件传输过程,则应该使用字节流来进行处理。客户端发送对话信息给2021服务器,服务器接收对话信息,并回话。

weixin_51293984的博客 1393

图解ADAS电源系统架构:看懂这张图,搞懂前装摄像头的供电秘密!

别以为ADAS系统就是“摄像头 + SoC”,其实最难搞的是供电系统,尤其是要满足车规级ASIL-D安全等级时。供电时序、电压稳定性、电源监控、冗余通信链路,一个都不能少。😤一旦电源选型不对,轻则系统卡顿,重则全车失控,不是闹着玩的。

weixin_43199439的博客 672

TCP程序设计之简单的文件传输程序设计

任务 设计服务端与客户端程序,从服务端输入要传送的文件路径,将文件传送给客户端,客户端接收文件并保存到指定位置。 服务端 #define _WINSOCK_DEPRECATED_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #include "WinSock2.h" #include "iostream" #include "fstream" ...

Megurine_Luka_的博客 1436

测试用例设计工具大盘点:总有一款适合你

本文旨在帮助测试工程师、开发人员及团队管理者快速了解主流测试用例设计工具的特点、适用场景和选择逻辑。覆盖工具类型包括传统文档工具、开源管理工具、商业集成平台及新兴AI工具,范围涵盖中小团队到大型企业的不同需求。本文从“测试用例设计的痛点”切入,用生活案例解释核心概念;接着按“工具类型”分类盘点主流工具(附优缺点对比表);再通过“小团队/中大型团队/敏捷团队”等真实场景教你选工具;最后展望AI等未来趋势,帮你“一次学透,终身受用”。

项目管理的博客 1590

《QGIS空间数据处理与高级制图》【目录】

《QGIS空间数据处理与高级制图》是一本面向GIS技术人员和学生的进阶手册,重点提升数据处理效率和专业制图标准化水平。全书涵盖空间数据预处理、矢量编辑、栅格处理、坐标系统应用和符号化设计等核心内容。书中详细介绍了批量数据转换、拓扑检查、遥感影像处理、自定义坐标系创建等实用技能,并提供了模型构建器和PyQGIS脚本实现自动化操作。通过大量实战案例和问题排查指南,帮助读者从基础使用进阶到专业应用,适合测绘、规划、环保等行业的GIS从业者参考使用。

LuckyHanMo的博客 372

JavaFX实现网络文件传输程序设计(互联网程序设计课程 第4讲)

互联网程序设计课程 第4讲 网络文件传输程序设计

GCTTTTTT的博客 975

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Web服务器实现文件传输程序设计

总体概括来说就是设计一个Web服务器的流程,将执行流程分为简单的步骤,每个步骤作为一个模块来实现。 1、整体设计 服务器程序发送文件给客户端或者从客户端接收文件,每次通信只能做一次文件传输,传输完毕后准备处理下一次通信。客户端程序,接收或者发送一个文件后就可以退出。因此,服务器短程序是一个死循环,处理一次之后不退出,继续监听。客户端程序处理一个连接就可以了。 2、客户端程序设...

F154879的博客 668

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Socket网络程序设计(3) ———— 利用tcp完成文件传输的设计和实现

用TCP/TP进行网际互连(3)———— 利用tcp完成文件传输的设计和实现 1.利用循环面向连接的模型完成固定文件的传输 2.由固定文件扩展成手动输入或选择文件 3.参考connectTCP的方式对程序进行抽象、封装

牧码杭城 5242

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

【计算机网络程序设计】多线程文件传输

服务器等待客户端连接 客户端连接服务器 客户端从标准输入获取上传文件名和上传线程数 客户端向服务器发送文件名和文件字节数 客户端根据输入线程数创建多个上传线程分别连接服务器 服务器从客户端各个上传线程接收数据,并根据客户端发送的文件名保存到本地 服务器根据客户端发送的文件字节数确认是否正确接收文件 服务器将接收结果通知客户端,断开连接

yaoyaxuan的博客 1329

Socket网络程序设计(4) ———— 实现linux和windows的文件传输

用TCP/TP进行网际互连(4)———— 实现linux和windows的文件传输 1.在循环面向连接的程序基础上,利用tcp完成linux和windows平台的文件传输 2.对服务器程序进行合理的封装优化 Linux服务器 + Windows客户端

牧码杭城 2623

python __file__怎么实现_Python实现基于HTTP文件传输实例

本文实例讲述了Python实现基于HTTP文件传输的方法。分享给大家供大家参考。具体实现方法如下:一、问题:因为需要最近看了一下通过POST请求传输文件的内容 并且自己写了Server和Client实现了一个简单的机遇HTTP的文件传输工具二、实现代码:Server端:#coding=utf-8from BaseHTTPServer import BaseHTTPRequestHandlerimp...

weixin_39610964的博客 183

#网络程序设计#实验二:利用TCP完成文件传输的设计和实现

文章目录实验目的实验原理实验内容实验结果 实验目的 输入文件路径,利用TCP实现客户文件向服务器的传输,并实现TCP的基本封装 实验原理 服务器 (1) 建立 socket (2) 确定服务器 scokaddr_in 结构体 (3)点分十进制 IP 转换 (4)使用 bind 绑定套接字 (5)使用 listen 监听 (6)使用 accept 接受连接请求 (7)accept 返回新的套接...

vircorns的博客 1915

网络程序设计——3.TCP/UDP实现跨平台文件传输

一、实验目的 在上次文件传输的程序基础上,利用循环面向连接、循环无连接方式完成linux和windows平台的文件传输,并完成客户端、服务器端代码的封装。 二、实验分析 1.使用TCP实现 在上次实验基础上,使用tcp_server.c的代码,只需修改为循环方式即可,然后作为Linux服务器使用 编写Windows下的客户端程序,进行文件发送 2.使用...

a429367172的博客 1823

计算机传输程序,计算机网络通信程序设计__TCP文件传输程序.pdf

;.目录一、实验名称: TCP文件传输程序 2二、实验要求 2三、总体规划 ...

weixin_29752563的博客 260
上一篇: 一个简易的用Socket API建立TCP通信程序Demo
下一篇: Python实现12306网站的余票查询
MagicScaring
博客等级 码龄11年 18粉丝 28原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值