vc+++网络文件传输
C语言基于socket的文件传输(可循环发送多个文件)
C语⾔基于socket的⽂件传输(可循环发送多个⽂件)基本简介:本次⽂件传输的实现主要是通过客户端向服务器发送下载请求,然后在服务器中找到对应的⽂件并打开⽂件,再继续向客户端传送⽂件,⽽客户端就在不停的接收。
这是因为⽂件可能⽐较⼤,⼀个缓冲数组只能保存⼀部分⽂件内容,因此服务器得不断从⽂件中读取内容并发给客户端,⽽客户端得不停的循环接收。
但是在事先,得将相应要发送的⽂件(照⽚,⾳频,视频等)保存在服务器相应的⽬录下。
⽽这个是不符合实际要求的,通常来讲,是应该将客户端1的⽂件发送给客户端2,⽽服务器仅仅只是起到⼀个中转站的作⽤,即⽂件应该事先保存在客户端1下。
这⾥我们只是完成⽂件传输的相应功能就⾏了,就不在计较这些啦。
因为只要你理解了这⼀块,可以根据⾃⼰的实际需要,在进⾏修改。
具体编译:gcc server.c -o server -lpthread //这是因为在服务器中加⼊了线程函数,所以编译的时候需要加上 -lpthread 。
gcc client.c -o client记住⼀定要先运⾏服务器,在运⾏客户端。
在客户端运⾏的时候回提醒你输⼊服务器对应的pc ip,如实输⼊就⾏啦。
如果是在本机pc上进⾏测试的话,也可以输⼊0.0.0.0 。
server.c:#include <stdio.h>#include <netdb.h>#include <sys/socket.h>#include <arpa/inet.h>#include <sys/types.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <fcntl.h>#include <netinet/in.h>#include <pthread.h>#define portnum 12345#define FILE_SIZE 500#define BUFFER_SIZE 1024void *net_thread(void * fd);int main(){//初始化套接字int server_fd=socket(AF_INET,SOCK_STREAM,0);if(-1==server_fd){perror("socket");exit(1);}//绑定端⼝和ip;struct sockaddr_in server_addr; //struct sockaddr_in为结构体类型,server_addr为定义的结构体server_addr.sin_family=AF_INET; //Internet地址族=AF_INET(IPv4协议)server_addr.sin_port=htons(portnum); //将主机字节序转化为⽹络字节序 ,portnum是端⼝号(server_addr.sin_addr).s_addr=htonl(INADDR_ANY);//IP地址if(-1==bind(server_fd,(struct sockaddr *)&server_addr,sizeof(server_addr))) //套接字与端⼝绑定{perror("bind");exit(6);}//开启监听if(-1==listen(server_fd,5)) //5是最⼤连接数,指服务器最多连接5个⽤户if(-1==listen(server_fd,5)) //5是最⼤连接数,指服务器最多连接5个⽤户{perror("listen");exit(7);}while(1){struct sockaddr_in client_addr;int size=sizeof(client_addr);int new_fd=accept(server_fd,(struct sockaddr *)&client_addr,&size); //server_fd服务器的socket描述字,&client_addr指向struct sockaddr *的指针,&size指向协议地址if(-1==new_fd){perror("accept");continue; //进⾏下⼀次循环}printf("accept client ip:%s:%d\n",inet_ntoa(client_addr.sin_addr),client_addr.sin_port);//inet_ntoa将⼀个⼗进制⽹络字节序转换为点分⼗进制IP格式的字符串。
VC文件上传和下载(FTP实现)
VC实现文件上传下载(FTP)//连接ftp服务器void CMyFtpDlg::OnConnect(){UpdateData(TRUE);//新建对话m_pInetSession=new CInternetSession(AfxGetAppName(),1,PRE_CONFIG_INTERNET_AC CESS);try{//新建连接对象m_pFtpConnection=m_pInetSession-> GetFtpConnection(m_strServer,m_strUserName, m_strPassword);}catch(CInternetException *pEx){//获取错误TCHAR szError[1024];if(pEx-> GetErrorMessage(szError,1024))AfxMessageBox(szError);elseAfxMessageBox( "There was an exception ");pEx-> Delete();m_pFtpConnection=NULL;return;}m_pRemoteFinder = new CFtpFileFind(m_pFtpConnection);//获得服务器根目录的所有文件并在列表框中显示BrowseDir( " ",&m_ctrlRemoteFiles,m_pRemoteFinder,&m_arrRemoteFiles);}//下载单个文件void CMyFtpDlg::DownFile(FILEITEM fileItem){if(fileItem.bDir == TRUE){AfxMessageBox( "本程序暂时不支持下载整个文件夹,请选择文件下载 ");}else{//格式化文件名CString strLocalFile,strRemoteFile;strRemoteFile.Format( "%s\\%s ",m_pRemoteFinder-> GetRoot(),fileItem.strFileName);strLocalFile.Format( "%s\\%s ",m_LocalFinder.GetRoot(),fileItem.strFileName);//下载if(m_pFtpConnection-> GetFile(strLocalFile,strLocalFile)){CString strMsg;strMsg.Format( "下载文件%s成功! ",fileItem.strFileName);AfxMessageBox(strMsg);}}}//上传单个文件void CMyFtpDlg::UpFile(FILEITEM fileItem){if(fileItem.bDir == TRUE){AfxMessageBox( "本程序暂时不支持上载整个文件夹,请选择文件上载 ");}else{//格式化文件名CString strLocalFile,strRemoteFile;strRemoteFile.Format( "%s\\%s ",m_pRemoteFinder-> GetRoot(),fileItem.strFileName);strLocalFile.Format( "%s\\%s ",m_LocalFinder.GetRoot(),fileItem.strFileName);//上传if(m_pFtpConnection-> PutFile(strLocalFile,strLocalFile)){CString strMsg;strMsg.Format( "上载文件%s成功! ",fileItem.strFileName);AfxMessageBox(strMsg);}}}欢迎您的下载,资料仅供参考!致力为企业和个人提供合同协议,策划案计划书,学习资料等等打造全网一站式需求。
虚拟主机云存储系统VCloudStorage及文件传输协议VCFTP
Virtual Host Cloud Storage System VCloudStorage and File Transfer Protocol VCFTP 作者: 陈晓华 李春芝 张鹏宇
作者机构: 湖州师范学院信息与工程学院,湖州313000
出版物刊名: 电信科学
页码: 59-66页
年卷期: 2011年 第7期
主题词: VCloudStorage VCFTP 文件传输协议 云存储 虚拟主机集群 整数规划模型
摘要:对于广域网下的文件传输和管理,云存储系统提供Web Service API、基于文件的API、基于Block的API和其他的API,通常需要在客户端安装特定程序调用这些API实现云存储功能,测试发现如果多人同时访问,传输文件失败率较高。
设计了基于Web Service、HTTP和Flash技术的文件传输协议VCFTP,开发了基于虚拟主机集群的云存储系统VCloudStorage。
首先建立SaaS服务模型,利用HTTP数据流存储技术,建立虚拟主机存储接口;接着建立虚拟主机传输能力、存储能力和价格能力数学模型,结合用户的传输请求建立文件传输整数规划数学模型及最优化算法,最终以此为基础设计了文件传输控制协议VCFTP。
VCFTP利用Flash跨平台和富客户端技术特点,无需在客户端部署其他程序;授权的用户根据传输请求、存储要求、服务水平和当前虚拟主机状态等条件,以传输能力最优化的方式进行文件传输。
实验结果表明VCFTP具有较高的性能和稳定性,VCloudStorage总吞吐量、平均传输率和文件传输成功率均优于微软SkyDrive存储、腾讯QQ邮箱存储和单虚拟主机存储。
本文提出的VCFTP增强了文件传输性能和稳定性,是提高广域网网络存储系统性能的一条有效途径。
用VC实现基于TCP_IP的局域网内点对点的大文件传输
梁 敏 1,陈万军 2
(1.西北民族大学 中国民族信息技术研究院,甘肃 兰州 730030;2.西北民族大学 计算机科学与信息工程学院, 甘肃 兰州 730030)
[摘 要] 文章对网络编程中涉及到的 TCP/IP 协议,讨论了 Winsock 通信机制核心技术,利用 VC++的 MFC 编写基
于客户/服务器模式的通信程序.实验结果表明:实现高达 99M 的文件无差错快速传输,耗时为 11s.
MB_ICONHAND|MB_OK);
return -1;
}
sockSrvrClose();
pDlg->ReceiveFile(recSo);
return 0;
}
//发送文件线程 UINT _SendThread(LPVOID lparam) {
CFileTransfersDlg* pDlg = (CFileTransfersDlg*) lparam; CSocket sockClient; if(!sockClientCreate()) {
MB_ICONHAND|MB_OK);
return -1;
}
pDlg->SendMessage(WM_ACCEPT_TRANSFERS); //接受连接
CSocket recSo;
if(!sockSrvrAccept(recSo))
{
::MessageBox((HWND)lparam, pDlg->GetError(GetLastError()),_T(" 错 误 "),
序编写中使用了 MFC 中的 CSocket 类,通过修改发送缓冲区和接收缓冲区的大小以及采用多线程技 术,解决了利用 Winsock 发送和接收大数据量文件的难题,满足了系统快速传输要求. 参考文献:
文件传输C语言实现
////////////////////////////////////#include <netinet/in.h> // for sockaddr_in#include <sys/types.h> // for socket#include <sys/socket.h> // for socket#include <stdio.h> // for printf#include <stdlib.h> // for exit#include <string.h> // for bzero#include <time.h> //for time_t and time#define HELLO_WORLD_SERVER_PORT 7754#define LENGTH_OF_LISTEN_QUEUE 20#define BUFFER_SIZE 1024int main(int argc, char **argv){struct sockaddr_in server_addr;bzero(&server_addr,sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = htons(INADDR_ANY);server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);// time_t now;FILE *stream;int server_socket = socket(AF_INET,SOCK_STREAM,0);if( server_socket < 0){printf("Create Socket Failed!");exit(1);}if( bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr))) {printf("Server Bind Port : %d Failed!", HELLO_WORLD_SERVER_PORT); exit(1);}if ( listen(server_socket, LENGTH_OF_LISTEN_QUEUE) ){printf("Server Listen Failed!");}while (1)struct sockaddr_in client_addr;socklen_t length = sizeof(client_addr);int new_server_socket = accept(server_socket,(struct sockaddr*)&client_addr,&length); if ( new_server_socket < 0){printf("Server Accept Failed!\n");break;}char buffer[BUFFER_SIZE];bzero(buffer, BUFFER_SIZE);strcpy(buffer,"Hello,World! ");strcat(buffer,"\n"); //send(new_server_socket,buffer,BUFFER_SIZE,0);bzero(buffer,BUFFER_SIZE);= recv(new_server_socket,buffer,BUFFER_SIZE,0);if (length < 0){printf("Server Recieve Data Failed!\n");exit(1);}printf("\n%s",buffer);if((stream = fopen("z.mp3","r"))==NULL){printf("The file 'data1' was not opened! \n");exit(1);}elseprintf("The file 'filename' was opened! \n");bzero(buffer,BUFFER_SIZE);int lengsize = 0;while((lengsize = fread(buffer,1,1024,stream)) > 0){printf("lengsize = %d\n",lengsize);if(send(new_server_socket,buffer,lengsize,0)<0){printf("Send File is Failed\n");break;}bzero(buffer, BUFFER_SIZE);}if(fclose(stream))printf("The file 'data' was not closed! \n");exit(1);close(new_server_socket);}close(server_socket);return 0;}//client.c////////////////////////////////////#include <netinet/in.h> // for sockaddr_in#include <sys/types.h> // for socket#include <sys/socket.h> // for socket#include <stdio.h> // for printf#include <stdlib.h> // for exit#include <string.h> // for bzero#include <time.h> //for time_t and time #include <arpa/inet.h>#define HELLO_WORLD_SERVER_PORT 7754#define BUFFER_SIZE 1024int main(int argc, char **argv){if (argc != 2){printf("Usage: ./%s ServerIPAddress\n",argv[0]);exit(1);}//time_t now;FILE *stream;struct sockaddr_in client_addr;bzero(&client_addr,sizeof(client_addr));client_addr.sin_family = AF_INET;client_addr.sin_addr.s_addr = htons(INADDR_ANY);client_addr.sin_port = htons(0);int client_socket = socket(AF_INET,SOCK_STREAM,0);if( client_socket < 0){printf("Create Socket Failed!\n");exit(1);}if( bind(client_socket,(struct sockaddr*)&client_addr,sizeof(client_addr))){printf("Client Bind Port Failed!\n");exit(1);}struct sockaddr_in server_addr;bzero(&server_addr,sizeof(server_addr));server_addr.sin_family = AF_INET;if(inet_aton(argv[1],&server_addr.sin_addr) == 0){printf("Server IP Address Error!\n");exit(1);}server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);socklen_t server_addr_length = sizeof(server_addr);if(connect(client_socket,(struct sockaddr*)&server_addr, server_addr_length) < 0) {printf("Can Not Connect To %s!\n",argv[1]);exit(1);}char buffer[BUFFER_SIZE];bzero(buffer,BUFFER_SIZE);int length = recv(client_socket,buffer,BUFFER_SIZE,0);if(length < 0){printf("Recieve Data From Server %s Failed!\n", argv[1]); exit(1);}printf("\n%s\n",buffer);bzero(buffer,BUFFER_SIZE);bzero(buffer,BUFFER_SIZE);strcpy(buffer,"Hello, World! From Client\n");send(client_socket,buffer,BUFFER_SIZE,0);if((stream = fopen("data","w+t"))==NULL){printf("The file 'data' was not opened! \n");}elsebzero(buffer,BUFFER_SIZE);length = 0;while( length = recv(client_socket,buffer,BUFFER_SIZE,0)) {if(length < 0){printf("Recieve Data From Server %s Failed!\n", argv[1]); break;}int write_length = fwrite(buffer,sizeof(char),length,stream); if (write_length<length){printf("File is Write Failed\n");break;}bzero(buffer,BUFFER_SIZE);}printf("Recieve File From Server[%s] Finished\n", argv[1]); fclose(stream);close(client_socket);return 0;}。
C语言实现UDP网络传输
C语言实现UDP网络传输UDP(User Datagram Protocol,用户数据报协议)是一种面向无连接的传输协议,它在网络编程中具有重要的作用。
本文将介绍C语言如何实现UDP网络传输的基本原理和步骤。
一、UDP网络传输简介UDP是一种简单的传输层协议,相对于TCP(Transmission Control Protocol,传输控制协议)来说,UDP更加轻量级。
它不提供可靠性和流量控制,但是具有实时性较高的特点,适用于需要快速传输数据的场景,如音频、视频等实时应用。
UDP协议的数据包格式主要包括源端口号、目标端口号、长度、校验和以及数据。
由于UDP是无连接的,所以每个数据包都是独立发送的,不需要建立和维护连接,这使得UDP的实现相对简单。
二、C语言实现UDP网络传输步骤要使用C语言实现UDP网络传输,我们需要按照以下步骤进行操作:1. 创建套接字(Socket)在C语言中,使用socket()函数创建一个套接字,该套接字用于后续的数据传输。
在创建套接字时,需要指定协议簇(AF_INET代表IPv4)和套接字类型(SOCK_DGRAM代表使用UDP协议)。
2. 绑定本地地址和端口号使用bind()函数将套接字与本地地址和端口号绑定,以便接收数据和发送数据。
通常将本地地址设置为INADDR_ANY,端口号可以自定义。
3. 接收数据使用recvfrom()函数接收远程主机发送的数据,该函数会将接收到的数据存储到指定的缓冲区中,并返回接收到的字节数。
可以通过指定发送方的地址和端口号来实现数据的精确接收。
4. 发送数据使用sendto()函数将数据发送给目标主机,该函数需要指定目标主机的地址和端口号,并将待发送的数据和数据长度作为参数传入。
5. 关闭套接字使用close()函数关闭套接字,释放资源。
三、C语言实现UDP网络传输示例代码```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <arpa/inet.h>#define MAX_BUFFER_SIZE 1024#define SERVER_PORT 8888#define SERVER_IP "127.0.0.1"int main() {int sockfd;char buffer[MAX_BUFFER_SIZE];struct sockaddr_in server_addr, client_addr;socklen_t client_len = sizeof(client_addr);// 创建套接字sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0) {perror("Error in creating socket");exit(1);}memset(&server_addr, 0, sizeof(server_addr));memset(&client_addr, 0, sizeof(client_addr));// 设置服务器地址和端口号server_addr.sin_family = AF_INET;server_addr.sin_port = htons(SERVER_PORT);server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);// 绑定本地地址和端口号if (bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {perror("Error in binding");exit(1);}printf("Server is listening for incoming connections...\n");while (1) {// 接收数据memset(buffer, 0, sizeof(buffer));ssize_t recv_len = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr*)&client_addr, &client_len);if (recv_len < 0) {perror("Error in receiving data");exit(1);}printf("Received data from client: %s\n", buffer);// 发送数据const char* msg = "Hello, client!";ssize_t send_len = sendto(sockfd, msg, strlen(msg), 0, (struct sockaddr*)&client_addr, client_len);if (send_len != strlen(msg)) {perror("Error in sending data");exit(1);}printf("Sent response to client: %s\n", msg);}// 关闭套接字close(sockfd);return 0;}```以上是一个简单的UDP服务器示例代码,它通过创建套接字、绑定地址和端口、接收数据并发送响应的方式来实现UDP网络传输。
vc+++网络文件传输
掌握实现网络文件传输的方法,并了解TCP连接是字符流的1.使用CSocket实现单线程文件传输2.应用多线程技术结合CAsyncSocket实现文件传输3.加入异常控制语句,增强程序的鲁棒性(Robust)4.了解如何提高套接字传输的速率及如何加强传输的稳定性·单线程文件传输:在第一章中曾经讲过用windows socket传输数据的方法,本章的单线程文件传输实验要在这个基础上融入文件操作,以实现基本的文件传输。
·多线程文件传输:在文件传输程序中,一个线程是一个搬运工,负责把文件数据从网络(看作是一条走廊)的一个端点搬到另一个端点;使用多线程,就相当于请了多个搬运工来做这项工作,效率自然会提高。
但是有一个疑问:“既然多个工人一起搬会提高工作进度,那是不是人越多越好呢?”——当然不是。
因为既然把网络看成一条走廊,那么当走廊中拥满了人的时候,这些人就成了搬运工作的瓶颈。
所以选择一个适当的线程数,对多线程传输的性能(传输速率)会有重要的影响(这一问题还会在后面探讨)。
由于多线程文件传输的实现涉及线程的同步的问题,所以实现和调试起来都有一定的困难。
但应当相信这是一项有趣的工作,因为多线程技术能把局域网传输的潜力充分的挖掘出来!建议读者再看实验步骤之前,先阅读一下文章末尾的【注意事项】一节。
这将有助于更好的理解本章的实现。
一.单线程文件传输(I):·服务器端(负责发送数据)的实现1.建立一个基于对话框的工程Server,并在建立的过程中选择支持windows socket。
2.在对话框上添加“发送”按钮。
3.为“发送”按钮添加事件BN_CLICKED的响应函数OnSend()。
void CServerDlg::OnSend(){// TODO: Add your control notification handler code hereCFileDialog fd(TRUE); // CFileDialog是MFC提供的一个用于选择文件的对话框类CString filename;char fn[40];CSocket listenSocket, socketSend;CFile file;long FileLength;char* data;if(IDOK==fd.DoModal()) // 启动用于选择文件的对话框{//选择了文件filename=fd.GetFileName(); // 获取用户选择的文件的文件名if(!file.Open(filename.GetBuffer(0),CFile::modeRead| File::typeBinary)){AfxMessageBox(" 打开文件错误,取消发送!");return;}strcpy(fn,filename.GetBuffer(0));}else return; //按了取消按钮listenSocket.Create(7000,SOCK_STREAM);listenSocket.Listen(5);listenSocket.Accept(socketSend);FileLength = file.GetLength(); // 获取文件的长度socketSend.Send(&FileLength, 4); // 把要发送的文件的长度传送给对方socketSend.Send(fn,40); // 发送要传送的文件的文件名data = new char[FileLength]; //分配一块和要传输的文件一样大小的内存空间file.ReadHuge(data, FileLength); //把文件中所有的数据一次性读入datasocketSend.Send(data, FileLength); //把data中的数据都发送出去file.Close();delete data;socketSend.Close();}·客户端(负责接收数据)的实现1.建立一个基于对话框的工程,并在建立的过程中选择支持windows socket。
基于VC 的Winsock 的文件传输程序的设计
基于VC 的Winsock 的文件传输程序的设计环境要求:Windows95/98/2000/XP功能要求:能将键盘上指定的文件发送到另一台计算机上;能将接收到的数据显示到屏幕窗口内,并显示收到文件的字节数和文件传输速率;一、设计目标用TC、Visual BASIC、Visual C++、Java 等编程工具和路由器、交换机、主机等网络设备提供的接口,解决网络用户之间的交互式对话问题,或计算通信网络的延迟、信道容量分配,或编码分析、通信协议分析,网络互连互通、网络规划。
进一步深入掌握网络设计和通信程序的设计原理。
使学生对计算机通信网络的设计实现有较深的了解,培养较高的通信网络设计能力。
本课设实验将基于2013版Visual Studio进行WINSOCK的文件传输的编程实现。
在WINDOWS95/98,WINDOWSNT进行WINSOCK开发使用的编程语言有很多,VC++,JAVA,DELPHI,VB等。
其中VC时使用最普遍,和WINSOCK结合最紧密的。
并且VC++对原来的WindowsSockets 库函数进行了一系列封装,继而产生了CAsynSocket、CSocket、CSocketFile等类,它们封装着有关Socket的各种功能,是编程变得更加简单。
SOCKET实际在计算机中提供了一个通信端口,可以通过这个端口与任何一个具有SOCKET 接口的计算机通信。
应用程序在网络上传输,接收的信息都通过这个SOCKET接口来实现。
在应用开发中就像使用文件句柄一样,可以对SOCKET句柄进行读,写操作。
二、设计原理套接字(Socket) 是一种网络编程接口,它是对通信端点的一种抽象,提供了一种发送和接收数据的机制。
套接字有两种类型:流式套接字(St ream Socket s) 和数据报套接字(Datagram Socket s) 。
数据报套接字提供了一种不可靠的、非连接的数据包通信方式,它使用用户数据报协议(UDP) ;而流式套接字可以将数据按顺序无重复地发送到目的地,它提供的是一种可靠的面向连接的数据传输方式。
C上传文件到服务器(含接收端源码)
C上传⽂件到服务器(含接收端源码)实例向⼤家展⽰了如何⽤Visual C#实现⽹络⽂件的下载,使⽤Visual C#进⾏Internet通讯编程是⾮常⽅便的。
在上⾯的程序中,我们仅仅⽤到了WebClient类的⼀些⽅法,⽽WebClient类不光提供了⽹络⽂件下载的⽅法,还提供了⽂件上传的⽅法【实例简介】⼀.概述:本⽂通过⼀个实例向⼤家介绍⽤Visual C#进⾏Internet通讯编程的⼀些基本知识。
我们知道.Net类包含了请求/响应层、应⽤协议层、传输层等层次。
在本程序中,我们运⽤了位于请求/响应层的WebRequest类以及WebClient类等来实现⾼抽象程度的Internet通讯服务。
本程序的功能是完成⽹络⽂件的下载。
⼆.实现原理:程序实现的原理⽐较简单,主要⽤到了WebClient类和FileStream类。
其中WebClient类处于名字空间中,该类的主要功能是提供向URI标识的资源发送数据和从URI标识的资源接收数据的公共⽅法。
我们利⽤其中的DownloadFile()⽅法将⽹络⽂件下载到本地。
然后⽤FileStream类的实例对象以数据流的⽅式将⽂件数据写⼊本地⽂件。
这样就完成了⽹络⽂件的下载。
三.实现步骤:⾸先,打开Visual ,新建⼀个Visual C# Windows应⽤程序的⼯程,不妨命名为"MyGetCar"。
接着,布置主界⾯。
我们先往主窗体上添加如下控件:两个标签控件、两个⽂本框控件、⼀个按钮控件以及⼀个状态栏控件。
最终的主窗体如下图所⽰:完成主窗体的设计,我们接着完成代码的编写。
在理解了基本原理的基础上去完成代码的编写是相当容易。
程序中我们主要⽤到的是WebClient类,不过在我们调⽤WebClient类的实例对象前,我们需要⽤WebRequest类的对象发出对统⼀资源标识符(URI)的请求。
try{WebRequest myre=WebRequest.Create(URLAddress);}catch(WebException exp){MessageBox.Show(exp.Message,"Error");}这是⼀个try-catch语句,try块完成向URI的请求,catch块则捕捉可能的异常并显⽰异常信息。
用C#实现局域网文件传输
网络通信一般都是通过Socket进行的,称为进程通信机制,通常也称作"套接字",用于描述ip地址和端口,是一个通信链的句柄。
先学习一下socket基本原理:socket原理:在Internet上有很多这样的主机,这些主机一般运行了多个服务软件,同时提供几种服务。
每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。
Socket 正如其英文原意那样,象一个多孔插座。
一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电,有的提供110伏交流电,有的则提供有线电视节目。
客户软件将插头插到不同编号的插座,就可以得到不同的服务。
Socket的形像理解:socket非常类似于电话插座。
以一个国家级电话网为例。
电话的通话双方相当于相互通信的2个进程,区号是它的网络地址;区内一个单位的交换机相当于一台主机,主机分配给每个用户的局内号码相当于socket号。
任何用户在通话之前,首先要占有一部电话机,相当于申请一个socket;同时要知道对方的号码,相当于对方有一个固定的socket。
然后向对方拨号呼叫,相当于发出连接请求(假如对方不在同一区内,还要拨对方区号,相当于给出网络地址)。
对方假如在场并空闲(相当于通信的另一主机开机且可以接受连接请求),拿起电话话筒,双方就可以正式通话,相当于连接成功。
双方通话的过程,是一方向电话机发出信号和对方从电话机接收信号的过程,相当于向socket发送数据和从socket接收数据。
通话结束后,一方挂起电话机相当于关闭socket,撤消连接。
Socket 通信应用示图TCP/IP 客户端/服务端通信流程图通过Socket通信原理的认识,下面可以开始写一个简单的通信程序,进行验证。
在这里,做了一个局域网内文件传输程序,其实模仿飞鸽传输的功能。
在公司里面是禁用QQ,不能使用QQ,有时发现挺麻烦的,传输文件不方便,搞得经常要用U盘来拷东西。
VisualC网络编程案例实战之简易网络文件传输器.pptx
• 01 ... //省略部分代码
• 0字2符c数ha组r *text[100];
//定义
• 03 CFile file('C:\例子.txt',CFile:modeReadWrite); //创建 文件对象
• 04 file.Read(text,100); //将文件数据读取到指定缓冲区 中
• 05 file.Write(text,100);//将缓冲区中的数据写到文件中
第10章 简易网络文件传输器
• 网络文件传输是一种基于网络平台的文件操作。通 过简易网络文件传输器可以将需要操作的文件通过 网络在两台计算机上实现数据异地传输功能。例如, 现在非常流行的P2P(点对点)传输功能就是通过网 络实现用户异地下载或上传文件。本章将讲解使用 socket和CFile类在两台主机上传输文件的方法。
• CFile file(“C:\例子.txt”,CFile:modeReadWrite); //创建文件对象
• 用户通过上面的代码,可以创建一个文件对象,并与指 定文件相关联,为其设置了打开方式为读写 “CFile::modeReadWrite”。
• 对于用户而言,以上两种构造函数在使用上均可以达到 目的。只是在打开文件时,前者需要显式地调用函数 Open()打开文件,而后者则在文件对象创建的同时打开 文件,属于隐式。
意义 创建新文件并覆盖原有文件 创建文件但不覆盖原有文件 以只读方式打开文件 以只写方式打开文件 以可读写方式打开文件 不允许其他进程读写文件 不允许其他进程读文件 不允许其他进程写文件 允许其他进程读写文件
毕业设计基于c的文件传输程序设计
目录前言 .............................................. 错误!未定义书签。
第一章 FTP简介..................................... 错误!未定义书签。
1.1 FTP传输机制............................... 错误!未定义书签。
1.2 FTP的数据类型............................. 错误!未定义书签。
第二章开发工具简介 ............................... 错误!未定义书签。
2.1 .C#简介.................................. 错误!未定义书签。
2.2. Visual Studio .NET........................ 错误!未定义书签。
2.2.1 Visual Studio .NET 的特色 (6)(1) 语言增强............................. 错误!未定义书签。
(2) Web 窗体............................. 错误!未定义书签。
(3) Windows 窗体......................... 错误!未定义书签。
(4) XML Web services..................... 错误!未定义书签。
(5) XML 支持............................. 错误!未定义书签。
2.3 .NET 框架................................. 错误!未定义书签。
第三章项目简介 ................................... 错误!未定义书签。
3.1 需求分析................................... 错误!未定义书签。
C#TcpClient网络编程传输文件的示例
C#TcpClient⽹络编程传输⽂件的⽰例⽬录⼀、简述⼆、内容⼀、简述 利⽤C# TcpClient在局域⽹内传输⽂件,可是⽂件发送到对⾯的时候却要重新命名⽂件的。
那可不可以连着⽂件名与⽂件⼀起发过去呢?⼆、内容 如上图,把⽂件名字符流的长度的值的字符流(这个⽂件名字符流长度的值固定是11位的字符串,不⾜11位前⾯补0)与⽂件名的字符流合为⼀个byte数组然后与⽂件发送到对⾯。
对⾯接收后解析出⽂件名字符流长度的值后,再根据长度解析出⽂件名,接下来再获取⽂件流。
服务端using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.IO;using ;using .Sockets;using System.Text;using System.Threading;using System.Windows.Forms;namespace TCPSendFile{public partial class Form1 : Form{public delegate void TxtReceiveAddContentEventHandler(string txtValue);public Form1(){InitializeComponent();}public void TxtAddContent(string txtValue){if (textBox1.InvokeRequired){TxtReceiveAddContentEventHandler addContent = TxtAddContent;textBox1.Invoke(addContent, new object[] { txtValue });}else{textBox1.Text = txtValue + "\r\n" + textBox1.Text;}}private void button1_Click(object sender, EventArgs e){TcpListener tcpListener = new TcpListener(IPAddress.Any, 18001);tcpListener.Start();textBox1.Text = "开始侦听...";Thread thread = new Thread(SendFileFunc);thread.Start(tcpListener);thread.IsBackground = true;}public void SendFileFunc(object obj){TcpListener tcpListener = obj as TcpListener;while (true){try{TcpClient tcpClient = tcpListener.AcceptTcpClient();if (tcpClient.Connected){NetworkStream stream = tcpClient.GetStream();string fileName = "testfile.rar";byte[] fileNameByte = Encoding.Unicode.GetBytes(fileName);byte[] fileNameLengthForValueByte = Encoding.Unicode.GetBytes(fileNameByte.Length.ToString("D11")); byte[] fileAttributeByte = new byte[fileNameByte.Length + fileNameLengthForValueByte.Length];fileNameLengthForValueByte.CopyTo(fileAttributeByte, 0); //⽂件名字符流的长度的字符流排在前⾯。
利用VC实现TFTP协议
传输的结束由 DATA 数据标记,数据区为 0-511 个字符。这个包可以被 ACK 数据包确认。 接收方在发出对最后数据包的确认后可以断开连接,当然,适当的等待是比较好的,如果最 后的确定包丢失可以再次传输。如果发出确认后仍然收到最后数据包,可以确定最后的确认 丢失。发送最后一个 DATA 包的主机必须等待对此包的确认或超时。如果响应是 ACK,传输 完成。如果发送方超时并不准备重新发送并且接收方有问题或网络有问题时,发送也正常结 束。也有可能这种情况传输是不成功的,但无论如何连接都将被关闭。
char *cmd;
//命令代码
int num;
//序号
int paramcount;
//参数个数
CMDFUNC callback; //回调函数名
}CMDNUM,*PCMDNUM;
/*定义帮助文档*/
char *helptext = "help:
显示帮助信息\n\
connect dest_ip:
3.3 初始链接
初始连接时候需要发出 WRQ(请求写入远程系统)或 RRQ(请求读取远程系统),收到 一个确定应答,是确定可以写出的包或应该读取的第一块数据。通常确认包包括要确认的包 的包号,每个数据包都与一个块号相对应,块号从 1 开始而且是连续的。因此对于写入请求 的确定是一个比较特殊的情况,因此它的包的包号是 0。如果收到的包是一个错误的包,则 这个请求被拒绝。创建连接时,通信双方随机选择一个 TID,是随机选择的,因此两次选择 同一个 TID 的可能性就很小了。每个包包括两个 TID,发送者 TID 和接收者 TID。这些 TID 用于在 UDP(或其他数据包协议)通信时选择端口,请求主机选择 TID 的方法上面已经说过了,
标准C语言实现基于TCPIP协议的文件传输
/*客户机源程序khj.c*/ #include >stdio.h> #include >sys/types.h> #include >sys/fcntl.h> #include >sys/socket.h> #include >sys/netinet/in.h> #include >netdb.h> #include >errno.h> #include >string.h> main() { char buf[1024],file[30]; char *strs=″ conveying,waiting...″; int target; register int k,s; struct sockaddr_in sin; struct hostent *hp; system(″clear″); printf(″ ″);
连接请求到达。连接成功后,该调用将用对端的地址结构和地址长度填充参数peer和addlen,如果对客户端的地址信息不感兴趣,这两个参 数用0代替。 5.客户端调用connect()与服务器建立连接。格式为: connect(int socketfd,struct sockaddr_in *servsddr,int addrlen) 客户端取得套接字描述符后,用该调用建立与服务器的连接,参数socketfd为socket()系统调用返回的套节字描述符,第二和第三个参数 是指向目的地址的结构及以字节计量的目的地址的长度(这里目的地址应为服务器地址)。调用成功返回0,否则将返回-1并设置errno。 6.通过软插座发送数据 一旦建立连接,就可以用系统调用read和write像普通文件那样向网络上发送和接受数据。Read接受三个参数:一个是套节字描述符; 一个为数据将被填入的缓冲区,还有一个整数指明要读的字节数,它返回实际读入的字节数,出错时返回-1,遇到文件尾则返回0。Write 也接受三个参数:一个是套节字描述符;一个为指向需要发送数据的缓冲区,还有一个整数指明要写入文件的字节个数,它返回实际写入的 字节数,出错时返回-1。当然,也可以调用send和recv来对套节字进行读写,其调用与基本的read和write系统调用相似,只是多了一个发 送方式参数。 7.退出程序时,应按正常方式关闭套节字。格式如下: int close(socketfd) 前面介绍了UNIX客户/服务器模式网络编程的基本思路和步骤。值得指出的是socket编程所涉及的系统调用不属于基本系统调用范围, 其函数原形在libsocket.a文件中,因此,在用cc命令对原程序进行编译时需要带-lsocket选项。 现在,我们可以针对文章开头提出的问题着手进行编程了。在图示的网络结构中,为使中心机房的服务器能和网点上的客户机进行通 信,需在服务器端添加通过路由器1 1 1 2到客户机的路由,两台客户机也必须添加通过路由器2 2 2 1到服务器的路由。在服务器的/etc/hosts 文件中应该包含下面内容: 1.1.1.1 server 2.2.2.2 cli1 2.2.2.3 cli2 客户机的/etc/hosts文件中应该有本机地址信息和服务器的地址信息,如cli1客户机的/etc/hosts文件: 2.2.2.2 cli1 1.1.1.1 server 网络环境搭建好后,我们可以在服务器端编写fwq.c程序,负责接受客户机的连接请求,并将从源文件中读取的数据发送到客户机。客 户机程序khj.c向服务器发送连接请求,接收从服务器端发来的数据,并将接收到的数据写入目标文件。
用vc++发送文件夹方法
关于发送文件夹的一方法VC作者:梦幻极光发送文件夹有很多方法,但是网上的代码很少,VC只有飞鸽有源代码,但是它采用的API的编程模式,不容易理解,加之注释又是日文或英文的,这样理解起来就更困难些.有很多人在网上发帖子询问如何发送文件夹,有人回答:用Winraar压缩再传,说实话是个方法,但是是个很无聊的方法.还有人说先遍历文件,发现是目录就叫对方建立一个.这个也是个方法,但是有些复杂,尤其是目录又深又多,难免出错.我要给大家介绍的方法是:1.先传把文件目录和文件名都传过去;2.处理文件目录以便建立.3.传输文件夹.首先,我们先定义一个结构体struct FOLDERINFO{int fileLength; //记录文件长度char fileName[128]; //记录文件名char filePath[512] //记录文件路径};这里需要说明一下,为什么文件名,文件路径不用CString定义,原因是这个结构体我们要发给对方的,但是由于CString长度是不丁长的,导致结构体长度不能确定,从而使程序出错.下面就是发送方的代码,我已经省去了目录选择和遍历目录的代码:void CMyQQDlg::SendFiles(){CSocket sockClient;sockClient.Create(); //创建SocketCString ip;m_You_IP.GetWindowText(ip); //m_You_IP是IP控件的变量sockClient.Connect(ip, 11024); /////////////////////////////////////////////////////////////////////CString fileName; ///////////////////////这是发送方处理目录的代码,如果没有这段代码fileName=m_fileName; //将只能发送根目录下的文件:)int a=fileName.Find(filepathone);if(a!=2){fileName=fileName.Right(fileName.GetLength()-a-1);fileName="C:\\"+fileName;}////////////////////////////////////////////////////////////////////////////CFile myFile;FOLDERINFO myFileInfo;if(!myFile.Open(m_fileName,CFile::modeRead|CFile::typeBinary))//m_fileName是遍历后得到的文件return ;myFileInfo.fileLength=myFile.GetLength(); //得到文件大小strcpy(myFileInfo.fileName,myFile.GetFileName()); //得到文件名称strcpy(myFileInfo.filePath,m_fileName);sockClient.Send(&myFileInfo,sizeof(myFileInfo)); //发送文件信息myFile.Seek(0,CFile::begin);char m_buf[SIZEFILE]={0}; //缓冲区CString strError;int num=0;int temp=0;//开始发送for(;;){num=myFile.Read(m_buf, SIZEFILE);if(num==0) break;end=sockClient.Send(m_buf, num);temp+=end;}myFile.Close();sockClient.Close();return ;}下面就是接收方的代码:int CMyQQDlg::SaveYouFiles(CSocket &recSo, SOCKADDR_IN &client){CString fnames;CString filenamepath;static int filescount=0;CString strfileIp,strfileName,strfileLength;char filemes[512]={0};//存文件名字的int fileLengths=0;FOLDERINFO myFileInfo;recSo.Receive(&myFileInfo,sizeof(FOLDERINFO));fileLengths=myFileInfo.fileLength;strfileIp.Format(inet_ntoa(client.sin_addr));strfileName.Format(myFileInfo.fileName); //得到文件名字strfileLength.Format("%f",myFileInfo.fileLength/1024.0);filenamepath.Format(myFileInfo.filePath); //得到文件路径int a=filenamepath.ReverseFind(_T('\\'));//这5行代码是用来得到一个例如:\AMD\Intel\ATI\ filenamepath=filenamepath.Left(a+1); //主要是用来建立目录CString b=filenamepath;a=b.ReverseFind(_T(':'));b=b.Right(b.GetLength()-a-1);filenamepath="files"+b; //所有的文件都存在files文件夹下CreateDirectory(filenamepath,NULL); //创建目录strcpy(filemes,filenamepath+strfileName);char bufs[SIZEFILE]={0}; //缓冲SIZEFILE=1024CFile fs(filemes,CFile::modeCreate|CFile::modeWrite); //存文件int n=0; //接受的字节数0表示结束int temp=0;//开始接收for(;;){n=recSo.Receive(bufs,SIZEFILE); //接受if(n==0) //0表示结束break; //接受完毕fs.Write(bufs,n);// fputs(bufs,fp);temp+=n;}fs.Close();return 0;}。
在VC++下实现视频数据文件的稳定传输
在VC++下实现视频数据文件的稳定传输
张加深;赵继广;王明东;苏小华
【期刊名称】《装备学院学报》
【年(卷),期】2002(013)002
【摘要】网络数据传输速度问题一直是人们关心的一个热点,以占用较多的服务器资源来换取网络速度的提高是多线程数据下载的一个前提.对国际互联网的传输协议作了介绍,如何实现文件的快速下载是讨论的主要内容,提供的方法适用于视频文件在网络中的稳定传输,并适合大文件的高速下载.同时也讨论了文件的续传问题.在VC++环境下实现文件的多线程传输,以达到高速数据传输的目的.
【总页数】3页(P60-62)
【作者】张加深;赵继广;王明东;苏小华
【作者单位】装备指挥技术学院,基础部,北京,101416;装备指挥技术学院,基础部,北京,101416;装备指挥技术学院,基础部,北京,101416;装备指挥技术学院,基础部,北京,101416
【正文语种】中文
【中图分类】TP311.1
【相关文献】
1.会议电视专用网络中数据文件传输的实现 [J], 孟晓秀;卢豫
2.VC++下读取FORTRAN数据文件应注意的问题 [J], 王日宏
3.用VC++实现卫星数据文件的自动转换 [J], 郝玉龙;梁霞
4.用VC++实现有限元数据文件输入的可视化 [J], 梁胜利;郭秉山
5.如何实现视频监控系统图像传输的稳定性 [J], 刘群峰
因版权原因,仅展示原文概要,查看原文内容请购买。
基于Visual C++6.0的点对点文件传输实现
学科分类号:_____08_____ 本科生毕业设计题目(中文):基于Visual C++6.0的点对点文件传输实现(英文):Design and Realization of Point-to-PointFiles Transfer with Visual C++6.0学生姓名:学号系部:专业年级:2指导教师:职称:目录摘要 (I)关键词 (I)Abstract (I)Key words (I)第一章绪论 (1)1.1 选题背景 (1)1.2 文件传输的主要方式 (1)1.3 课题研究意义 (3)第二章 TCP/IP技术与C/S模式 (4)2.1 TCP/IP技术 (4)2.1.1 TCP/IP体系结构 (4)2.1.2 TCP/IP特点 (5)2.1.3 TCP/IP传送文件机制 (6)2.3 客户机/服务器模式 (7)第三章 Winsock网络程序设计技术 (8)3.1 Winsock简介 (8)3.2 Winsock通信机制 (9)3.3 Winsock编程模型 (11)3.3.1 建立一个Socket (11)3.3.2 配置一个Socket (11)3.3.3 使用Socket (12)第四章系统方案设计 (14)4.1B/S 结构与C/S结构的选择 (14)4.1.1 B/S结构与C/S结构 (14)4.1.2 C/S模式的采用 (15)4.2 文件传输协议的比较 (16)4.2.1 早期文件传输协议的研究比较 (16)4.2.2 HTTP协议传输文件的方式 (17)4.2.3 FTP文件传输协议的研究 (18)4.3 建立新的利用套接字方式的通信协议 (18)第五章系统详细设计 (20)5.1 系统总体设计 (20)5.2 系统功能模块设计 (21)5.2.1 服务器模块 (21)5.2.2 客户端模块 (25)5.2.3 界面显示模块 (26)致谢 (28)参考文献 (29)基于Visual C++6.0的点对点文件传输实现摘要:近年来,随着Internet 的发展和普及,人们对网络传输的需求量越来越大,远程教育、网络会议等众多新兴软件的产生,对大文件的传输问题提出了挑战。
C++实现文件传输
c++实现文件传输之一:框架结构和界面实现在木马中文件管理的重要性,是无需质疑的,对于文件的管理,做到并不难,但做好却也不易在我们编写一个功能完整的“文件木马”其实现效果如图所示。
为了文章的完整性,我们将分为数篇来介绍,本文主要介绍程序的整体框架和界面实现,在以后的文章中将以此框架为基础实现详细的功能。
实现:枚举磁盘,枚举目录,获取文件信息上传文件,下载文件,执行文件,创建目录,删除目录等传输控制结构要实现客户端与服务端的通信,设计一个合理的传输控制结构,会使后面的工作轻松很多,为了使代码易读首先对要使用的命令进行预定义其各个命令定义如下#define GetDriver 0x01 //磁盘信息#define GetDirInfo 0x02 //目录信息#define ExecFile 0x03 //执行文件#define GetFile 0x04 //下载文件#define PutFile 0x05 //上传文件#define DelFile 0x06 //删除文件#define DelDir 0x07 //删除目录#define CreateDir 0x08 //创建目录#define FileInfo 0x09 //文件信息#define GetScreen 0x10 //查看屏幕在程序的网络通信中主要有操作命令 ,命令对像,和具体数据三部分,对于命令的传输定义如下结构typedef struct{int ID; //操作命令BYTE lparam[BUF_LEN*2]; //命令对像}COMMAND;因为在程序中打交道最多的就是文件,对文件的详细属性定义如下结构typedef struct{char FileName[MAX_PATH]; //文件名称int FileLen; //文件长度char Time[50]; //时间信息BOOL IsDir; //为目录否BOOL Error; //错误信息HICON hIcon; //图标句柄}FILEINFO;服务端结构服务端还是比较简单的其整体思路如下1.服务端循环接受连接,并把连接交给线程处理2.线程接受"命令数据",并跟据命令ID将命令对像和SOCKET句柄传给处理函数3.函数执行指定功能,并返回执行结果对整体结构的描述,我们用伪代码表述如下main(){ /*初示化设置......*/while(true){if(client=accept(server,(sockaddr *)&clientaddr,&len))//循环接受连接{CreateThread(NULL,NULL,SLisen,(LPVOID)client,NULL,NULL);//传递线程处理}}/*清理释放资源......*/WSACleanup();}服务端程序运行后循环接受连接,如果有新的连接就传递给新的线程处理,线程代码如下DWORD WINAPI SLisen(LPVOID lparam){SOCKET client=(SOCKET)lparam;COMMAND command;while(1){if(recv(client,(char*)&command,sizeof(command),0)==SOCKET_ERROR)//接受命令数据{cout<<"The Clinet Socket is Closed/n";break;}else{switch(command.ID)//判断命令ID{case GetDriver://将命令对像和SOCKET句柄传递给处理函数GetDriverProc (command,client);break;case DelFile:DelFileProc (command,client);break;/*其它命令......*/}}}}线程式的功能是接受客户端的"命令数据",并跟跟据命令ID 将命令对像传递给处理函数,由函数完成指定的功能以删除文件命令为例其函数格式如下DWORD DelFileProc (COMMAND command,SOCKET client){if(DeleteFile((char*)command.lparam)==0)//command.lparam为命令对像,这里为要删除的文件路径{send(client,"删除失败...");}else{send(client,"删除成功...");}}很容易看出,处理函数接受"命令对像"和客户端SOCKET句柄,执行后会把结果传递回去....客户端结构客户端结构的实现思路如下1.跟服务端建立连接2.发送用户命令3.启动一个线程,用于接受服务端的返回信息对整体结构的描述,我们用伪代码表述如下void CMyDlg::OnConnect(){if(connect(server,(SOCKADDR*)&serveraddr,sizeof(serveraddr))<0)//连接....{return ;}CreateThread(NULL,NULL,CLisen,this,NULL,NULL);//创建线程用于接受SERVER返回信息}对于用户发送的命令我们仍以删除文件为例说明其代码如下void CMyDlg::OnMenuDelFile(){HTREEITEM CurrentNode = m_tree.GetSelectedItem(); //取得选择的节点CString FullPath =GetFullPath(CurrentNode); //取得节点全目录COMMAND command;command.ID=DelFile; //设置命令为删除文件 //删除文件command.lparam=FullPath.LockBuffer()); //将路径加入命令对像send(server,command);}用于接受SERVER返回信息的线程,和服务端接受命令线程相似,这里就不再说明了,有兴趣可以看下源代码到这里程序的流程框架就介绍完了,下面我们再看一下程序的界面设置.界面实现程序的主界面如上图所示,主程序是一个对话框,主要包括一个树控件m_tree 和列表控件m_list分别用于显示磁盘目录和文件,在对话框初示化时用以下代码设置树控件的属性DWORD dwStyle = GetWindowLong(m_tree.m_hWnd,GWL_STYLE);dwStyle |=TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT; SetWindowLong(m_tree.m_hWnd,GWL_STYLE,dwStyle);对于列表框控件则没有太多要求,要留意的是,如果显示图标应该把Styles显示属性设置为ICONVC的做出的界面,常常让人有种摔键盘的冲动。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
掌握实现网络文件传输的方法,并了解TCP连接是字符流的1.使用CSocket实现单线程文件传输2.应用多线程技术结合CAsyncSocket实现文件传输3.加入异常控制语句,增强程序的鲁棒性(Robust)4.了解如何提高套接字传输的速率及如何加强传输的稳定性·单线程文件传输:在第一章中曾经讲过用windows socket传输数据的方法,本章的单线程文件传输实验要在这个基础上融入文件操作,以实现基本的文件传输。
·多线程文件传输:在文件传输程序中,一个线程是一个搬运工,负责把文件数据从网络(看作是一条走廊)的一个端点搬到另一个端点;使用多线程,就相当于请了多个搬运工来做这项工作,效率自然会提高。
但是有一个疑问:“既然多个工人一起搬会提高工作进度,那是不是人越多越好呢?”——当然不是。
因为既然把网络看成一条走廊,那么当走廊中拥满了人的时候,这些人就成了搬运工作的瓶颈。
所以选择一个适当的线程数,对多线程传输的性能(传输速率)会有重要的影响(这一问题还会在后面探讨)。
由于多线程文件传输的实现涉及线程的同步的问题,所以实现和调试起来都有一定的困难。
但应当相信这是一项有趣的工作,因为多线程技术能把局域网传输的潜力充分的挖掘出来!建议读者再看实验步骤之前,先阅读一下文章末尾的【注意事项】一节。
这将有助于更好的理解本章的实现。
一.单线程文件传输(I):·服务器端(负责发送数据)的实现1.建立一个基于对话框的工程Server,并在建立的过程中选择支持windows socket。
2.在对话框上添加“发送”按钮。
3.为“发送”按钮添加事件BN_CLICKED的响应函数OnSend()。
void CServerDlg::OnSend(){// TODO: Add your control notification handler code hereCFileDialog fd(TRUE); // CFileDialog是MFC提供的一个用于选择文件的对话框类CString filename;char fn[40];CSocket listenSocket, socketSend;CFile file;long FileLength;char* data;if(IDOK==fd.DoModal()) // 启动用于选择文件的对话框{//选择了文件filename=fd.GetFileName(); // 获取用户选择的文件的文件名if(!file.Open(filename.GetBuffer(0),CFile::modeRead| File::typeBinary)){AfxMessageBox(" 打开文件错误,取消发送!");return;}strcpy(fn,filename.GetBuffer(0));}else return; //按了取消按钮listenSocket.Create(7000,SOCK_STREAM);listenSocket.Listen(5);listenSocket.Accept(socketSend);FileLength = file.GetLength(); // 获取文件的长度socketSend.Send(&FileLength, 4); // 把要发送的文件的长度传送给对方socketSend.Send(fn,40); // 发送要传送的文件的文件名data = new char[FileLength]; //分配一块和要传输的文件一样大小的内存空间file.ReadHuge(data, FileLength); //把文件中所有的数据一次性读入datasocketSend.Send(data, FileLength); //把data中的数据都发送出去file.Close();delete data;socketSend.Close();}·客户端(负责接收数据)的实现1.建立一个基于对话框的工程,并在建立的过程中选择支持windows socket。
(为了能够利用Server端的代码,在程序编写时,可以复制Server的代码到Client目录,并在Server的基础上修改或添加代码)2.在对话框上添加“接收”按钮。
3.为“发送”按钮添加事件BN_CLICKED的响应函数OnReceive ()。
void CServerDlg::OnReceive(){// TODO: Add your control notification handler code hereCSocket socketReceive;CFile file;long FileLength;char * data;char fn[40];socketReceive.Create();socketReceive.Connect("127.0.0.1", 7000); //这里为了测试的方便,我们使用127.0.0.1本地回路IPsocketReceive.Receive(&FileLength, 4); //获取要接受的文件的长度socketReceive.Receive(fn, 40); //获取要接受的文件的文件名data = new char[FileLength];socketReceive.Receive(data, FileLength); //获取要接受的文件内容file.Open(fn,CFile::modeCreate|CFile::modeWrite | CFile::typeBinary); //在当前目录建立文件file.WriteHuge(data, FileLength);file.Close();delete data;socketReceive.Close();AfxMessageBox("接收文件成功");}上面的程序以最简单的方式实现了文件传输功能。
但正是因为它的简单,所以忽略了很多重要的东西。
读者读到这里的时候可以考虑一下可能存在着些什么问题。
在这里给出一些上面程序的不足:1.在本书的原理部分曾经提到阻塞式和非阻塞式两种套接字的工作方式。
在上面的程序中使用的CSocket类提供了阻塞式的服务,这令编写程序非常方便。
然而这却不利于程序的友好性和可用性——服务器端在没有获得客户端连接的时候固执的侦听,一点也不理会用户的命令。
对话框不再响应消息,用户只能用强制关闭来结束程序。
2.希望一次性地动态分配整个文件大小的堆存贮区作为读入数据的内存空间。
这个空间一方面受到堆大小的限制,另一方面也受到CFile类成员函数ReadHuge()和WriteHuge()的读写能力限制,还有Receive()和Send()函数一次能够发送的数据也以其参数的最大值为限,所以在遇到大中型文件的时候,系统将不能满足程序提出的动态分配大块内存的要求,这样传输便不得不终止。
3.在实际的网络传输中,网络情况是十分多变和复杂的。
通过CSocket的成员函数们的返回值可以了解传输的状态,然而在上面的程序中却没有使用这些异常控制,带来的直接后果就是当遇到网络拥塞或对方传送的数据暂时未到时,程序就会认为传输结束而出乎意料的终止。
4.在上面的程序中,程序没有传送文件的属性数据,而只通过套接字传送文件数据。
在实际应用中这种假设通常是不存在的,所以应当把文件属性也传给对方,以达到文件的完全复制。
改进方法:1.使用CAsyncSocket实现异步套接字,避免阻塞2.化整为零,把文件分若干次读入并发送3.在程序中加入异常控制语句已应付网络多变的情况4.在传送文件数据之前获取文件属性值传给对方下面将给出基于上述改进方案的前三点而重新编写的程序,对于第四点,有兴趣的读者可以自己实现。
二.单线程文件传输(II):·服务器端(负责发送数据)的实现1.建立一个基于对话框的工程Server,并在建立的过程中选择支持windows socket。
2.在对话框上添加“侦听”,“发送”按钮。
3.用Class Wizard添加一个派生于CAsyncSocket的类CMySocket。
4.添加CMySocket类的全局变量listenSocket用于侦听。
添加CMySocket类全局变量的位置,最宜在MySocket.cpp的头部。
如下:// MySocket.cpp : implementation file//#include "stdafx.h"#include "Server.h"#include "MySocket.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CMySocketCMySocket listenSocket;CMySocket::CMySocket(){}CMySocket::~CMySocket(){}本章中以后所有的CMySocket型全局变量都应仿效本段程序添加。
5.添加CMySocket类的全局变量sendSocket,用于传输数据6.为“发送”按钮添加事件BN_CLICKED的响应函数OnSend() #define ReadSize 500void CServerDlg ::OnSend(){// TODO: Add your control notification handler code hereCFile file;char data[ReadSize]; // 用于存放读入的文件数据块long ByteSended=0, FileLength,count;CFileDialog fd(TRUE);CString filename;char fn[40];if(IDOK==fd.DoModal()) // 启动用于选择文件的对话框{//选择了文件filename=fd.GetFileName(); //获取选择的文件的文件名if(!file.Open(filename.GetBuffer(0),CFile::modeRead|CFile::typeBinary)){AfxMessageBox("打开文件错误,取消发送!");return;}strcpy(fn,filename.GetBuffer(0));}else return; //按了取消按钮FileLength=file.GetLength();sendSocket.Send(&FileLength,sizeof(long));sendSocket.Send(fn,40);memset(data,0,sizeof(data));do{// 从文件读取数据,每次最多读入ReadSize个字节。