TCP文件传输程序的设计书
计算机网络技术第四版课程设计
计算机网络技术第四版课程设计一、设计题目本次计算机网络技术课程设计的题目是“基于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协议的实现技术要点,并实现了文件传输过程中常见的断点续传功能和命令行控制。
这些技术点均是计算机网络技术课程中的重点内容,对我们深入学习和理解计算机网络技术的概念和应用具有重要的帮助和启示。
设计文档及使用说明
大作业:网络Socket编程程序员:熊宇龙200630501407 信息安全5班本程序实现了多客户端访问和一定大小内的文件传输(已测试bmp和txt文件),并且客户端在连接时就将得到服务器端的文件列表。
为方便解说起见,我将研发说明文档和操作说明集中在这里一起了声明:部分源码来自参考书《WINDOWS网络编程》中的TCP连接部分,本程序也是基于其源码上进行了大幅度修改完成的。
大部分研发说明都在程序内写出来了。
我特地用红字表示出来。
其中主要是表示的拓展的地方、需要注意的地方,以及核心的地方。
其他说明:由于时间不够的缘故,本程序旨在实现其传输文件的功能、列表发送以及多客户端多线程传输的功能。
并没有对其人性化进行太多设计,程序员可以按照我在程序中的提示通过直接修改程序达到其他目的(如扩大传输量),主要可修改的包括:1.文件列表,保存在1.txt中可以任意修改,不过请不要对客户端造成欺骗。
2.Buff容量,通过修改DEFAULT_BUFFER 达到目的。
拓展构想:计划内却因为时间关系未完成的的部分包括1.实现任意大小文件传输:可以通过if语句判定大小,产生多个buff文件顺序传输并顺序写入。
不难但是时间不够了。
2.实现断点续传:判定部分遇到了困难,未完成。
具体操作流程图请见最后程序如下:客户端:// Client.c// 声明:部分代码来自《WINDOWS网络编程》一书中关于建立TCP连接的部分// 功能:连接到服务器端并下载文件// 注意:build时请在工程设置中添加ws2_32.lib//// Command Line Options:// client [-p:x] [-s:IP] [-n:x] [-o]// -p:x Remote port to send to// -s:IP Server's IP address or hostname// -n:x Number of times to send message// -o Send messages only; don't receive//#include <iostream.h>#include <winsock2.h>#include <stdio.h>#include <stdlib.h>#define DEFAULT_COUNT 20#define DEFAULT_PORT 5150#define DEFAULT_BUFFER 4096//希望调整最大可传输文件大小请调整此处不要忘了将server的也同样更改#define DEFAULT_MESSAGE "This is a test of the emergency \broadcasting system"char szServer[128],szMessage[1024];int iPort = DEFAULT_PORT;DWORD dwCount = DEFAULT_COUNT;BOOL bSendOnly = FALSE;void usage(){printf("usage: client [-p:x] [-s:IP] [-n:x] [-o]\n\n");printf(" -p:x Remote port to send to\n");printf(" -s:IP Server's IP address or hostname\n");printf(" -n:x Number of times to send message\n");printf(" -o Send messages only; don't receive\n");ExitProcess(1);}void V alidateArgs(int argc, char **argv){int i;for(i = 1; i < argc; i++){if ((argv[i][0] == '-') || (argv[i][0] == '/')){switch (tolower(argv[i][1])){case 'p':if (strlen(argv[i]) > 3)iPort = atoi(&argv[i][3]);break;case 's':if (strlen(argv[i]) > 3)strcpy(szServer, &argv[i][3]);break;case 'n':if (strlen(argv[i]) > 3)dwCount = atol(&argv[i][3]);break;case 'o':bSendOnly = TRUE;break;default:usage();break;}}}}int main(int argc, char **argv){WSADATA wsd;SOCKET sClient;char szBuffer[DEFAULT_BUFFER];int ret;struct sockaddr_in server;struct hostent *host = NULL;cout<<"input szServer"<<endl;//这里输入目标服务器地址如果没有输入就会返回错误请使用服务器IP地址cin>>szServer;//如果在本机测试,可使用127.0.0.1本机循环地址作为这个数值ValidateArgs(argc, argv);if (WSAStartup(MAKEWORD(2,2), &wsd) != 0){printf("Failed to load Winsock library!\n");return 1;}strcpy(szMessage, DEFAULT_MESSAGE);sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (sClient == INV ALID_SOCKET){printf("socket() failed: %d\n", WSAGetLastError());return 1;}server.sin_family = AF_INET;server.sin_port = htons(iPort);server.sin_addr.s_addr = inet_addr(szServer);//连接到目标地址if (server.sin_addr.s_addr == INADDR_NONE){host = gethostbyname(szServer);if (host == NULL){printf("Unable to resolve server: %s\n", szServer);return 1;}CopyMemory(&server.sin_addr, host->h_addr_list[0],host->h_length);}if (connect(sClient, (struct sockaddr *)&server,sizeof(server)) == SOCKET_ERROR){printf("connect() failed: %d\n", WSAGetLastError());return 1;}ret = recv(sClient, szBuffer, DEFAULT_BUFFER, 0);//等待接收文件列表if (ret == SOCKET_ERROR){printf("recv() failed: %d\n", WSAGetLastError());}szBuffer[ret] = '\0';printf("FileList:\n");printf("%s\n", szBuffer);FILE *fp;while(1){cout<<"input szMessage"<<endl;//根据文件列表发起申请下载目标文件cin>>szMessage;ret = send(sClient, szMessage, strlen(szMessage), 0);if (ret == 0){break;}else if (ret == SOCKET_ERROR){printf("send() failed: %d\n", WSAGetLastError());break;}printf("Send %d bytes\n", ret);if (!bSendOnly){ret = recv(sClient, szBuffer, DEFAULT_BUFFER, 0);//接收文件的szBuff并开始准备转换回文件if (ret == 0)break;else if (ret == SOCKET_ERROR){printf("recv() failed: %d\n", WSAGetLastError());break;}szBuffer[ret] = '\0';printf("RECV [%d bytes]: '%s'\n", ret, szBuffer);char s[10]="RECV"; //对接受的文件进行重命名在前面加上RECV 后几句都是此作用strncat(s,szMessage,strlen(szMessage));fp=fopen(s,"a+");fwrite(szBuffer,1,ret,fp);fclose(fp);}}closesocket(sClient);WSACleanup();return 0;}服务器端:// Server.c// 声明:部分代码来自《WINDOWS网络编程》一书中关于建立TCP连接的部分// 功能:建立一个全自动服务器,当收到连接申请则连接并发送文件列表,并等待客户端发送申请下载请求// 注意:build时请在工程设置中加入ws2_32.lib#include <winsock2.h>#include <stdio.h>#include <stdlib.h>#define DEFAULT_PORT 5150#define DEFAULT_BUFFER 4096int iPort = DEFAULT_PORT;BOOL bInterface = FALSE,bRecvOnly = FALSE;char szAddress[128];//// Function: usage//// Description:// Print usage information and exit//void usage(){printf("usage: server [-p:x] [-i:IP] [-o]\n\n");printf(" -p:x Port number to listen on\n");printf(" -i:str Interface to listen on\n");printf(" -o Don't echo the data back\n\n");ExitProcess(1);}void V alidateArgs(int argc, char **argv){int i;for(i = 1; i < argc; i++){if ((argv[i][0] == '-') || (argv[i][0] == '/')){switch (tolower(argv[i][1])){case 'p':iPort = atoi(&argv[i][3]);break;case 'i':bInterface = TRUE;if (strlen(argv[i]) > 3)strcpy(szAddress, &argv[i][3]);break;case 'o':bRecvOnly = TRUE;break;default:usage();break;}}}}DWORD WINAPI ClientThread(LPVOID lpParam)//多线程控制通过给不同的客户不同的线{SOCKET sock=(SOCKET)lpParam;char szBuff[DEFAULT_BUFFER];int ret,nLeft,idx;FILE *fp;while(1){ret = recv(sock, szBuff, DEFAULT_BUFFER, 0);//收听客户端想下载什么文件if (ret == 0)break;else if (ret == SOCKET_ERROR){printf("recv() failed: %d\n", WSAGetLastError());break;}szBuff[ret] = '\0';printf("RECV: '%s'\n", szBuff);fp=fopen(szBuff,"rb");//打开目标文件将目标文件内容存入szBuffmemset(szBuff,0,DEFAULT_BUFFER);//初始化szBuff 不然传送的数据后面会自动添加很多东西ret=fread(szBuff,1,DEFAULT_BUFFER-1,fp);//将目标文件中的东西读入szBuffsend(sock,szBuff,ret,0);//发送给客户端fclose(fp);}return 0;}int main(int argc, char **argv){WSADATA wsd;SOCKET sListen,sClient;int iAddrSize;HANDLE hThread;DWORD dwThreadId;struct sockaddr_in local,client;ValidateArgs(argc, argv);if (WSAStartup(MAKEWORD(2,2), &wsd) != 0){printf("Failed to load Winsock!\n");return 1;}sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (sListen == SOCKET_ERROR){printf("socket() failed: %d\n", WSAGetLastError());return 1;}if (bInterface){local.sin_addr.s_addr = inet_addr(szAddress);if (local.sin_addr.s_addr == INADDR_NONE)usage();}elselocal.sin_addr.s_addr = htonl(INADDR_ANY);local.sin_family = AF_INET;local.sin_port = htons(iPort);if (bind(sListen, (struct sockaddr *)&local,sizeof(local)) == SOCKET_ERROR){printf("bind() failed: %d\n", WSAGetLastError());return 1;}listen(sListen, 8);while (1){iAddrSize = sizeof(client);sClient = accept(sListen, (struct sockaddr *)&client,&iAddrSize);if (sClient == INV ALID_SOCKET){printf("accept() failed: %d\n", WSAGetLastError());break;}printf("Accepted client: %s:%d\n",inet_ntoa(client.sin_addr), ntohs(client.sin_port));char fileList[DEFAULT_BUFFER]="";//创建文件表地址FILE*fp;fp=fopen("1.txt","r");//读取文件表,文件表默认为保存在1.txt中int flen=fread(fileList,1,DEFAULT_BUFFER,fp);send(sClient,fileList,flen,0);flen=0;hThread = CreateThread(NULL, 0, ClientThread, //多线程控制(LPVOID)sClient, 0, &dwThreadId);if (hThread == NULL){printf("CreateThread() failed: %d\n", GetLastError());break;}CloseHandle(hThread);}closesocket(sListen);WSACleanup();return 0;}操作流程:1.编译过程请在工程—设置—连接—工程、选项中添加ws2_32.lib 不然link过程会出现错误。
基于TCP协议的简单即时通信软件的设计与实现(含源文件)
基于TCP协议的网络通信系统的设计与实现摘要:网络通信,由于其具有实时性、跨平台性、成本低、效率高等优点而受到广泛的使用.设计并实现一个能够处理多用户进行实时、安全的即时通信系统具有较强的现实意义。
即时通信的底层通信是通过SOCKET套接字接口实现的。
当前的主流UNIX系统和微软的WINDOWS系统都在内核提供了对SOCKET字接口的支持。
使用这个统一的接口,可以编写一个可移植的TCP/IP通信程序。
使信息能够在INTERNET上可靠的传输。
本文设计并实现了基于局域网内的简单即时通信系统,系统采用C/S模式,底层通信通过SOCKET套接字接口实现,服务器负责客户端的登录验证,好友信息的保存和心跳报文的发送.客户端采用P2P方式实现消息传递,并能实现文件的传输。
本文首先讨论了同步套接字,异步套接字,多线程并发执行任务等;然后阐述了客户端、服务器如何使用XML序列化的消息进行通信。
关键词:即时通信;文件传输;套接字;TCP协议Abstract :Instant messages have several advantages such as real-time, cross-platform, cheap a nd efficient. To design a Multi-user IM (instant message) architecture is very importan t in both theory and realism。
Instant message based on TCP/IP protocol that is realiz ed by socket interface。
Almost all UNIX operation systems and Microsoft's window s operation systems provide support of socket in the kernel. Using the uniform interfa ce, we can develop a portable program of TCP/IP, which help us transfer informatio n in Internet safely and credibly。
网络文件传输系统的设计与实现
网络文件传输系统的设计与实现作者指导老师摘要:在科学技术飞速发展的今天,Internet已经和人们的日常生活息息相关,无论是工作,学习还是娱乐,都离不开网络。
比如有时候需要进行文件的传输,虽然现在的许多网络文件传输工具能基本满足人们对文件传输质量的要求,但是它们往往都存在安全性,工作效率低等问题。
本课程设计的文件传输系统是在Windows操作系统下,Visual C + + 6.0环境下借用WinSock控件实现的,是基于TCP/IP协议的C/S模式,在服务器和客户端分别以socket为中心进行编程,客户端和服务器端的界面分别是由文件发送模块和文件接收模块组成。
客户端先调用connect()与服务器建立连接,然后用send()发送数据;服务器端先调用listen()侦听客户端的连接请求,然后调用accept()对连接请求进行响应,如果需要接收数据,则会调用receive()接收。
本文件传输系统成功的实现了服务器和客户端的文件传输,不论是较小范围内的局域网还是远程网,而且还可以传输多种格式的文件,如word,视频,图像等。
相比其它文件传输工具而言,本系统有很多的优点。
首先,界面简单,易于操作;其次,传输较大的文件时,不需要花费很长时间。
关键词:文件传输;WinSock ; socket编程; C/S结构目录1 绪论 (3)1.1选题背景 (3)1.2选题意义 (3)2开发环境及相关技术简介 (4)2.1开发环境Visual C++ 6.0介绍 (4)2.2基于vc的socket网络编程的基本原理 (4)2.2.1 socket的基本概念 (4)2.2.2Winsock网络编程原理 (5)2.3 TCP/IP协议简介 (5)2.5 C/S结构 (6)2.5.1 C/S结构的概念 (6)2.5.2 C/S结构的工作模式 (6)2.5.3 C/S结构的优点 (6)3 网络文件传输系统的设计 (6)3.1服务器端和客户端界面介绍 (7)3.1.1服务器界面介绍 (7)3.1.2客户端界面介绍 (7)3.2服务器端,客户端程序分析 (8)3.2.1服务器端分析 (8)3.2.2客户端分析 (12)4实现 (16)4.1系统运行环境 (16)4.2文件传输系统的测试 (16)4.2.1实验一:局域网内文件传输 (16)4.2.2实验二:远程网络上文件传输 (18)4.2.3实验三:较大文件的传输 (20)4.2.4实验四:不同格式文件的传输 (20)4.3该文件传输系统的不足 (21)5结论 (21)致谢 (22)参考文献 (23)1 绪论1.1选题背景21世纪被称为信息时代,因为计算机技术的迅猛发展,给人们的日常生活以及工作,都带来翻天覆地的变化。
实验一-文件传输协议设计
实验一:文件传输协议的设计与实现目录1.实验设计目的和要求2.背景知识3.课程设计分析4.程序清单5.运行结果6.总结1.课程设计目的和要求文件传输是各种计算机的网络的基本功能,文件传送协议是一种最基本的应用层协议。
它是按照客户或服务器模式进行的工作,提供交式的访问。
是INTERNRT使用最广泛的协议之一。
以及深入了解计算机网络是建立在TCP/IP网络体系结构上。
用 socket 编程接口编写俩个程序,分别为客户程序和服务器程序1.掌握TCP/IP 网络应用程序基本的设计方法;2.用socket 编程接口编写两个程序,分别为客户程序(client.c)和服务器程序(server.c);3.撰写课程设计说明书。
装订后的课程设计说明书不少于10面(含封面、任务书、目录、正文、参考文献、成绩评定表、封底)。
2.背景知识第一个FTP的RFC由A.K.Bhushan 在1971年提出,同时由MIT 与Harvard实验实现,RFC 172提供了主机间文件传输的一个用户级协议。
长期发展过程由于底层协议从NCP改变为TCP,RFC765定义了采用TCP的FCP.FTP协议在今天已经发展成熟,应用也越来越广很多开发的比较成熟的FTP 客户端软件已经得到了广泛的应用.3.课程设计分析Server端Client端创建ServerSocket对象,在某端口提供监听服务Client端等待来自Client端的服务请求接受Client端的请求,用返回的创建Socket对象,向ServerSocket建立连接的监听端口请求通过向Socket中读写数据来通过向新的Socket中读写数与Client端通信据来与Server端通信关闭Socket,结束与Server端的通信关闭Socket,结束与当前Client的通信,等待其他请求关闭ServerSocket对象,结束监听服务4.程序清单:1.服务器源代码:#include <Winsock2.h>#include <stdio.h>#include <iostream>using namespace std;#pragma comment(lib, "wsock32.lib")#define PORT 4523char buf_send[1024];char buf_rec[1024];SOCKET sockSrv;//socket初始化DWORD CreateSocket(){WSADATA WSAData;//WSADATA结构被用来保存函数WSAStartup返回的Windows Sockets初始化信息if(WSAStartup(MAKEWORD(2,2),&WSAData)!=0)//WSAStartup完成winsock的初始化{printf("socket initialize failed!\n");return (-1);}sockSrv=socket(AF_INET,SOCK_STREAM,0);//定义为面向连接的,返回值送给sockSrvif(sockSrv==SOCKET_ERROR){printf("socket create failed ! \n");WSACleanup();//中止Windows Sockets DLL的使用return(-1);}SOCKADDR_IN addrSrv;//TCP/IP使用SOCKADDR_IN 定义地址addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//计算机IP地址addrSrv.sin_port=htons(PORT);//协议端口号addrSrv.sin_family=AF_INET;//地址所属协议簇//绑定端口if(bind(sockSrv,(struct sockaddr FAR *)&addrSrv,sizeof(addrSrv))==SOCKET_ERROR){printf("Bind Error");return(-1);}return (1);}int SendFileRecord(SOCKET datatcps,WIN32_FIND_DATA *pfd)//用于回复给客户端{char filerecord[MAX_PATH+32];FILETIME ft;FileTimeToLocalFileTime(&pfd->ftLastWriteTime,&ft);//将一个FILETIME结构转换成本地时间SYSTEMTIME lastwtime;//系统时间FileTimeToSystemTime(&ft,&lastwtime);//根据一个FILETIME结构的内容,装载一个SYSTEMTIME 结构char *dir=pfd->dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY?"<DIR>":" ";sprintf(filerecord,"%04d-%02d-%02d %02d:%02d %5s %10d %-20s\n",lastwtime.wYear,lastwtime.wMonth,lastwtime.wDay,lastwtime.wHour,lastwtime.wMinute,dir,pfd->nFileSizeLow,pfd->cFileName);if(send(datatcps,filerecord,strlen(filerecord),0)==SOCKET_ERROR)//发送回复失败{printf("Error occurs when sending file list!\n");return 0;}return 1;}//发送主机文件目录int SendFileList(SOCKET datatcps){HANDLE hff;WIN32_FIND_DATA fd; //获取和更改文件属性hff=FindFirstFile("*",&fd);//搜索文件if(hff==INVALID_HANDLE_VALUE)//搜索无效返回值{const char *errstr="can't list files!\n";cout<<"list file error!"<<endl;if(send(datatcps,errstr,strlen(errstr),0)==SOCKET_ERROR){cout<<"error occurs when sending file list!"<<endl;}closesocket(datatcps);return 0;}BOOL fMoreFiles=TRUE;//BOOL型,返回值为大于0的整数时为TRUE,返回值为0时候,为FALSE,返回值为-1时为ERROR。
c++文件传输毕业设计
c++文件传输毕业设计摘要:本文描述了一个基于C++的文件传输系统的设计与实现。
该系统具有高效和安全的特点,并且采用了TCP/IP协议进行数据传输。
系统分为客户端和服务器端,客户端可以将本地文件传输到服务器端,服务器端可以接收并保存文件。
在设计过程中,使用了文件流、套接字编程和多线程技术。
通过对系统进行测试和评估,验证了其稳定性和可靠性。
最终结果表明,该文件传输系统能够快速、安全地传输大文件,并且能够满足用户的需求。
1. 引言文件传输是计算机网络中常见的任务之一。
随着互联网的发展和普及,文件传输系统需要具备高效、安全、稳定和可靠等特点。
本文设计了一个基于C++的文件传输系统,该系统通过TCP/IP协议进行数据传输,能够满足用户的需求。
2. 系统设计2.1 系统结构文件传输系统分为客户端和服务器端两部分。
客户端提供了文件选择和传输功能,服务器端则负责接收和保存文件。
2.2 数据传输系统基于TCP/IP协议进行数据传输,使用套接字编程进行通信。
客户端通过套接字将文件内容划分为较小的数据块并发送给服务器端,服务器端再将接收到的数据块组合成完整的文件。
2.3 多线程技术为了提高系统的传输效率,使用了多线程技术。
客户端和服务器端均开启多个线程进行文件传输,从而实现并发传输。
3. 系统实现3.1 客户端实现客户端使用C++编写,通过用户界面提供文件选择的功能。
客户端接收用户选择的文件,并将文件内容划分为数据块进行传输。
客户端还可显示传输进度和传输结果。
3.2 服务器端实现服务器端使用C++编写,通过套接字接收客户端传输的数据块。
服务器端将接收到的数据块组合成完整的文件,并保存到本地磁盘中。
服务器端还可显示传输进度和传输结果。
4. 系统测试与评估为了验证系统的稳定性和可靠性,对系统进行了测试。
通过传输大文件和多个文件,评估系统的传输速度和传输成功率。
测试结果表明,系统能够快速、安全地传输大文件,并且具有良好的稳定性和可靠性。
文件传输协议的简单设计与实现
文件传输协议的简单设计与实现摘要:文件传送是各种计算机网络都实现的基本功能,文件传送协议是一种最基本的应用层协议按照客户/服务器的模式进行工作,提供交互式的访问,是INTERNET使用最广泛的协议之一。
本设计是用JAVA语言简单实现文件传输协议,利用SOCKET 以及SERVERSOCKE等类方法,当中实现了上传、下载、获取服务器目录等基本文件传输功能。
关键字:文件传输、FTP。
1 具体设计任务1(1实验内容我们的计算机网络实验环境建立在TCP/IP 网络体系结构之上。
各计算机除了安装TCP/IP 软件外,还安装了TCP/IP 开发系统。
实验室各计算机具备Windows环境中套接字socket 的编程接口功能,可为用户提供全网范围的进程通信功能。
本实验要求学生利用这些功能,设计和实现一个简单的文件传送协议。
1(2具体要求用socket 编程接口编写两个程序,分别为客户程序(client.c)和服务器程序(server.c),该程序应能实现下述命令功能:get:取远方的一个文件put:传给远方一个文件pwd:显示远主当前目录dir:列出远方当前目录cd :改变远方当前目录, :显示你提供的命令quit :退出返回此命令的具体工作方式(指给出结果的形式)可以参照FTP 的相应命令,有余力的同学可以多实现几个命令。
2 基本思路及所涉及的相关理论2.1 文件传输协议网络协议是网络中计算机与终端之间正确传送信息和数据的规范格式,起包括语法、语义和时序这三部分。
文件传输协议(File Transfer Protocol, FTP)是在TCP/IP网络中传输文件的一种格式规范,其规定在用户和服务器之间开设两个通信端口:控制端口和数据端口。
前者生存周期为从用户登录开始直至用户登出,后者则在进行数据传送的时候打开,并且在数据传送完毕之后立即结束。
控制端口用来监听双方共同规定的控制字以达到及时提供服务或响应,数据端口则要先将文件拆分成分组再进行传送,这样做的目的是为了更加好的适应网络中的带宽限制,以及减少传送期间节点的延时,以达到高速传送。
基于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) ;而流式套接字可以将数据按顺序无重复地发送到目的地,它提供的是一种可靠的面向连接的数据传输方式。
基于局域网的文件传输系统的设计与实现
基于局域网的文件传输系统的设计与实现一、系统需求分析首先,我们需要明确系统的需求。
基于局域网的文件传输系统应该具备以下功能:1、快速传输:能够在局域网内实现高速文件传输,减少传输时间,提高工作效率。
2、安全性:对传输的文件进行加密处理,确保文件内容的保密性和完整性。
3、稳定性:在网络环境不稳定的情况下,依然能够保证文件传输的可靠性,不会出现文件丢失或损坏的情况。
4、多用户支持:允许多个用户同时使用系统进行文件传输,且每个用户都有自己的权限和存储空间。
5、操作简便:系统界面简洁直观,用户能够轻松上手,无需复杂的培训。
二、系统设计(一)总体架构设计系统采用客户端服务器(C/S)架构。
服务器端负责管理用户信息、文件存储和传输控制,客户端则负责与用户进行交互,实现文件的上传、下载等操作。
(二)功能模块设计1、用户管理模块:用于注册、登录、修改用户信息等操作。
2、文件传输模块:实现文件的上传、下载、删除等功能。
3、权限管理模块:为不同用户设置不同的权限,如只读、读写等。
4、加密模块:对传输的文件进行加密和解密,保障文件安全。
5、日志管理模块:记录系统的操作日志,便于追踪和审计。
(三)数据库设计建立数据库来存储用户信息、文件信息、权限信息等。
用户表包括用户 ID、用户名、密码等字段;文件表包括文件 ID、文件名、文件路径、文件大小等字段;权限表包括用户 ID、文件 ID、权限类型等字段。
(四)网络协议选择选用 TCP/IP 协议作为系统的网络通信协议,保证数据传输的可靠性和稳定性。
三、系统实现(一)服务器端实现1、使用 Java 或 C++等编程语言实现服务器端的逻辑。
2、建立监听端口,等待客户端的连接请求。
3、处理客户端的注册、登录等请求,并验证用户信息。
4、接收客户端上传的文件,存储到指定位置,并更新数据库中的文件信息。
5、响应客户端的下载请求,将文件发送给客户端。
(二)客户端实现1、使用相应的编程语言开发客户端界面,提供简洁直观的操作界面。
文件传输协议的简单设计与实现
文件传输协议的简单设计与实现课程名称运算机网络课程设计题目名称文件传输协议的简单设计与实现学生学院专业班级___ _学号学生姓名______ _________指导教师______ _____2010 年 1 月 5 日设计摘要关键词:SOCKET编程,FTPclient/server程序摘要:本课程设计包含了文件传输协议的简单设计与实现。
文件传送是各种运算机网络实现的差不多功能,文件传送协议是一种最差不多的应用层协议按照客户/服务器的模式进行工作,提供交互式的访问,是INTERNET使用最广泛的协议之一。
文件传输协议的简单设计与实现建立在运算机网络实验环境TCP/IP 网络体系结构之上,使用socket 编程接口编写两个程序,分别为客户程序(client.c)和服务器程序〔server.c〕,实现下述命令功能:get , put, pwd, dir, cd, ?, quit 等,利用了已有网络环境设计并实现简单应用层协议。
本设计包括了具体设计任务,差不多思路及所涉及的相关理论,设计流程图,调试过程中显现的问题及相应解决方法,实验运行结果,核心程序,个人体会及建议等。
名目1、文件传输协议的简单设计与实现------------------------------18 1. 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 网络体系结构之上。
C#_TCP发送消息和传输文件
【背景】最近做了一个双机备份,就是服务器上有个文件夹,会接收客户端传来的文件,而我们要做的就是同步这台服务器和另一台备用服务器上的文件.为了实现这个功能我们使用的tcp点对点传输.【开发环境】VS2005【实现原理】要实现同步要解决两个问题,一个是获取本地服务器上上传上来的文件,二是实现两台机器间的文件传输.第一个问题我们用的FileSystemWatcher这个可以监视指定文件夹下的文件变动,然后我们把变动的文件信息记录到数据库,在指定的时间间隔后同步两台机器的文件.第二个问题我们用的tcp文件传输,我们按照一定的原则通过传输消息来告知备份服务器的要传输的文件名称和大小,然后传输文件.【代码】1:FileSystemWatcher监视文件变动的就不介绍了,很简单的winform控件应用. 2:为了完成文件传输,我做了一个TcpHelper类库,其中包括TcpCommon,TcpClientHelper,TcpListenerHelper三个类,TcpCommon主要实现了文件传输时用的一些公共的方法比如发送接收文件,发送接收消息,和文件hash的计算TcpCommonusing System;using System.Collections.Generic;using System.Text;using System.Security.Cryptography;using System.IO;using .Sockets;namespace Xpwy.Backup.PTcpHelper{internal class TcpCommon{private static readonly int _blockLength = 500 * 1024;///<summary>///计算文件的hash值///</summary>internal string CalcFileHash(string FilePath){MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvid er();byte[] hash;using (FileStream fs = new FileStream(FilePath, FileMode. Open, FileAccess.Read, FileShare.Read, 4096)){hash = puteHash(fs);}return BitConverter.ToString(hash);}///<summary>///发送文件///</summary>///<param name="filePath"></param>///<param name="stream"></param>///<returns></returns>internal bool SendFile(string filePath, NetworkStream stream) {FileStream fs = File.Open(filePath, FileMode.Open);int readLength = 0;byte[] data = new byte[_blockLength];//发送大小byte[] length = new byte[8];BitConverter.GetBytes(new FileInfo(filePath).Length).Copy To(length, 0);stream.Write(length, 0, 8);//发送文件while ((readLength = fs.Read(data, 0, _blockLength)) > 0) {stream.Write(data, 0, readLength);}fs.Close();return true;}///<summary>///接收文件///</summary>///<param name="filePath"></param>///<param name="stream"></param>///<returns></returns>internal bool ReceiveFile(string filePath, NetworkStream stre am){try{long count = GetSize(stream);if (count == 0){return false;}long index = 0;byte[] clientData = new byte[_blockLength];if (File.Exists(filePath)){File.Delete(filePath);}string path=new FileInfo(filePath).Directory.FullName;if (!Directory.Exists(path)){Directory.CreateDirectory(path);}FileStream fs = File.Open(filePath, FileMode.OpenOrCr eate);try{//计算当前要读取的块的大小int currentBlockLength = 0;if (_blockLength < count - index){currentBlockLength = _blockLength;}else{currentBlockLength =(int)( count - index);}int receivedBytesLen = stream.Read(clientData, 0, currentBlockLength);index += receivedBytesLen;fs.Write(clientData, 0, receivedBytesLen);while (receivedBytesLen > 0 && index < count){clientData = new byte[_blockLength];receivedBytesLen = 0;if (_blockLength < count - index){currentBlockLength = _blockLength;}else{currentBlockLength = (int)(count - index); }receivedBytesLen = stream.Read(clientData, 0, currentBlockLength);index += receivedBytesLen;fs.Write(clientData, 0, receivedBytesLen);}}catch (Exception ex){return false;}finally{fs.Close();}}catch (Exception ex){return false;}return true;}///<summary>///发送消息///</summary>///<param name="message"></param>///<param name="stream"></param>///<returns></returns>internal bool SendMessage(string message, NetworkStream strea m){byte[] data = Encoding.UTF8.GetBytes(message);byte[] resultData = new byte[8 + data.Length];BitConverter.GetBytes(data.Length).CopyTo(resultData, 0);data.CopyTo(resultData, 8);stream.Write(resultData, 0, resultData.Length);return true;}///<summary>///读取消息///</summary>///<param name="stream"></param>///<returns></returns>internal string ReadMessage(NetworkStream stream){string result = "";int messageLength = 0;byte[] resultbyte = new byte[500 * 1024];//读取数据大小int index = 0;int count = GetSize(stream);byte[] data = new byte[count];while (index < count && (messageLength = stream.Read(dat a, 0, count - index)) != 0){data.CopyTo(resultbyte, index);index += messageLength;}result = Encoding.UTF8.GetString(resultbyte, 0, index);return result;}///<summary>///获取要读取的数据的大小///</summary>///<param name="stream"></param>///<returns></returns>private int GetSize(NetworkStream stream){int count = 0;byte[] countBytes = new byte[8];try{if (stream.Read(countBytes, 0, 8) == 8){count = BitConverter.ToInt32(countBytes, 0);}else{return0;}}catch (Exception ex){}return count;}}}TcpClientHelperusing System;using System.Collections.Generic;using System.Text;using .Sockets;namespace Xpwy.Backup.PTcpHelper{public class TcpClientHelper:IDisposable{TcpClient client;NetworkStream netstream;string _serverip = "127.0.0.1";int _port = 8080;TcpCommon tcpCommon = new TcpCommon();#region TcpClientHelper constructorpublic TcpClientHelper(string strServerIP, int serverPort) {_serverip = strServerIP;_port = serverPort;}#endregionpublic void Start(){client = new TcpClient(_serverip, _port);netstream = client.GetStream();}public void Stop(){if (netstream != null){netstream.Close();}if (client != null){client.Close();}}#region TcpCommon所有方法public string CalcFileHash(string FilePath){return tcpCommon.CalcFileHash(FilePath);}public bool SendFile(string filePath){return tcpCommon.SendFile(filePath, netstream);}public bool ReceiveFile(string filePath){return tcpCommon.ReceiveFile(filePath, netstream); }public bool SendMessage(string message){return tcpCommon.SendMessage(message, netstream); }public string ReadMessage(){return tcpCommon.ReadMessage(netstream); }#endregion#region IDisposable 成员public void Dispose(){if (netstream != null){netstream.Close();}if (client != null){client.Close();}}#endregion}}TcpListenerHelperusing System;using System.Collections.Generic;using System.Text;using .Sockets;using ;using System.Threading;namespace Xpwy.Backup.PTcpHelper{public class TcpListenerHelper{private string _strServerIP = "";private int _serverPort = 0;TcpListener server;TcpClient client;NetworkStream netstream;IAsyncResult asyncResult;TcpCommon tcpCommon = new TcpCommon();ManualResetEvent listenConnected = new ManualResetEvent(fals e);bool _active = false;public TcpListenerHelper(string strServerIP, int serverPort) {_strServerIP = strServerIP;_serverPort = serverPort;server = new TcpListener(IPAddress.Parse(strServerIP), se rverPort);server.Server.ReceiveTimeout = 6000;server.Server.SendTimeout = 6000;}///<summary>///启动///</summary>public void Start(){try{_active = true;server.Start();}catch (Exception ex){throw ex;}}///<summary>///停止///</summary>public void Stop(){try{_active = false;if (client != null){client.Close();}if (netstream != null){netstream.Close();}server.Stop();}catch (Exception ex){throw ex;}}public void Listen(){listenConnected.Reset();asyncResult = server.BeginAcceptTcpClient(new AsyncCallba ck(AsyncCall), server);}public void AsyncCall(IAsyncResult ar){try{TcpListener tlistener = (TcpListener)ar.AsyncState;if (_active){client = tlistener.EndAcceptTcpClient(ar);netstream = client.GetStream();}else{client = null;netstream = null;}listenConnected.Set();}catch (Exception ex){throw ex;}}public bool WaitForConnect(){listenConnected.WaitOne();if (client != null && netstream != null){return true;}else{return false;}}#region TcpCommon所有方法///<summary>///计算文件的hash值///</summary>public string CalcFileHash(string FilePath){return tcpCommon.CalcFileHash(FilePath);}///<summary>///发送文件///</summary>///<param name="filePath"></param>///<returns></returns>public bool SendFile(string filePath){return tcpCommon.SendFile(filePath, netstream);}///<summary>///接收文件///</summary>///<param name="filePath"></param>///<returns></returns>public bool ReceiveFile(string filePath){return tcpCommon.ReceiveFile(filePath, netstream); }///<summary>///发送消息///</summary>///<param name="message"></param>///<returns></returns>public bool SendMessage(string message){return tcpCommon.SendMessage(message, netstream);}///<summary>///接收消息///</summary>///<returns></returns>public string ReadMessage(){return tcpCommon.ReadMessage(netstream);}#endregion#region IDisposable 成员public void Dispose(){Stop();}#endregion}}3:调用的代码server端:public void DoWork(object state){TcpListenerHelper tlistener = (TcpListenerHelper)state; tlistener.Listen();//监听while (tlistener.WaitForConnect())//等待知道监听到了连接{try{string firstMessage = "";while (!string.IsNullOrEmpty((firstMessage = tlis tener.ReadMessage()))){if (firstMessage.ToLower() == "filebak".ToLower()){tlistener.SendMessage("filebakok");#region文件备份string filepath = bine(Environmen t.CurrentDirectory, "FileBak\\" + tlistener.ReadMessage()).ToString(); tlistener.ReceiveFile(filepath);if (tlistener.CalcFileHash(filepath) == t listener.ReadMessage()){tlistener.SendMessage("ok");}else{tlistener.SendMessage("wrong");}#endregion}else if (firstMessage.ToLower() == "DBBak".To Lower()){#region数据库备份tlistener.SendMessage("dbbakok");string filename = tlistener.ReadMessage();string filepath = bine(System.Env ironment.CurrentDirectory, "DBBak") +"\\"+ filename;//接收文件tlistener.ReceiveFile(filepath);//验证hash值string hash = tlistener.ReadMessage();if (hash == tlistener.CalcFileHash(filepa th))tlistener.SendMessage("ok");elsetlistener.SendMessage("wrong");#endregion}}catch{}tlistener.Listen();//监听下一个连接}}client端:private void FileBackup(object arg){TcpClientHelper client = (TcpClientHelper)arg;//获取需备份的文件DataTable dt = this._oFileWatch.GetBackupFiles();if (dt != null){for (int i = 0; i < dt.Rows.Count; i++){client.SendMessage("FileBak");if (client.ReadMessage().ToLower() == "filebakok") {client.SendMessage(dt.Rows[i]["RelativePath"]. ToString());client.SendFile(dt.Rows[i]["FullPath"].ToStri ng());client.SendMessage(client.CalcFileHash(dt.Rows[i]["FullPath"].ToString()));if (client.ReadMessage().ToLower() == "ok"){LOGClass.WriteLog("备份文件【" + dt.Rows[i] ["FullPath"].ToString() + "】成功");}else{LOGClass.WriteLog("备份文件【" + dt.Rows[i] ["FullPath"].ToString() + "】失败。
1C#利用TCP实现文件传输
listener.Start(); //循环,等待客户端连接
while (true) {
const int bufferSize = 256; //接受客户端的连接,利用client保存连接的客户端
MemoryStream memStream = new MemoryStream(); int bytesRead = 0; do { //获取服务器端的回应,
bytesRead = clientStream.Read(responseBuffer, 0, bufferSize); //服务器的回应写入到memStream
TcpClient client = listener.AcceptTcpClient(); //获取客户端的流stream
NetworkStream clientStream = client.GetStream(); byte[] buffer = new byte[bufferSize]; int readBytes = 0; //将客户端流读入到buffer中 readBytes = clientStream.Read(buffer, 0, bufferSize); //将从客户端流读取的数据保存到字符串request中 string request = Encoding.ASCII.GetString(buffer).Substring(0, readBytes); //如果客户端的命令以LIST开头, if (request.StartsWith("LIST")) {
//将data中的文件内容写入到客户端clientStream中,传回客户端 clientStream.Write(data, 0, data.Length);
计算机网络编程实验报告(实现TCP、UDP数据传输)
package internet;
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import .Socket;
package internet;
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import .ServerSocket; import .Socket;
建立 Socket 连接至少需要一对套接字,其中一个运行于客户端,称为 ClientSocket ,另一个运行于服务器端,称为 ServerSocket 。
套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。 服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接 的状态,实时监控网络状态,等待客户端的连接请求。
public class UDPserver { public static void main(String[] args) throws IOException{ /* * 接收客户端发送的数据 */ DatagramSocket socket=new DatagramSocket(10086); // 创 建 服 务 器 端
的连接
System.out.println(s.getInetAddress().getHostAddress()+"...connection");
网络课程设计任务书(完整)
课程设计说明书
发送TCP数据包
起止日期:2010年06月28日至2010年07月02日
学生姓名
班级
学号
成绩
指导教师(签字)
计算机与通信学院
2010年7月02日
湖南工业大学
课程设计任务书
2009—2010学年第二学期
计算机与通信学院(系、部)通信工程专业071班级
课程名称:计算机网络原理
具体任务
1.初始化原始套接字
2.发送TCP数据包
时间安排与完成情况
6月28号,查找好相关资料、理解原理、并分配好任务
6月29号,熟悉了解初始化原始套接字的过程
6月30号,熟悉并且了解发送数据包的过程
7月01号,把两者结合起来,实现程序的功能
7月02号,编写调试,并且撰写课程设计报告
一、设计目的:
设计一个发送TCP数据包的程序,并根据本设计说明TCP数据包的结构以及TCP协议与IP协议的关系,使大家对TCP协议的工作原理有更深入的认识。
size -=sizeof(USHORT);
}
if(size)
{
cksum += *(UCHAR*)buffer;
}
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (USHORT)(~cksum);
}
int main(int argc, char* argv[])
{
printf("setsockopt SO_SNDTIMEO error!\n");
计算机网络课程设计--数据包发送和接受程序的实现
计算机网络课程设计一数据包发送和接受程序的实现《计算机网络》课程设计数据包发送和接受程序的实现计算机学院软件工程10级⑷班3110006379陈泳蒸2012年12月21日数据包发送和接受程序的实现一、设计题目与要求1.设计题目发送TCP数据包2.设计要求本设计的功能孚填充一个TCP数据包,并发送给目的主机。
1)以命令行形式运行:SendTCP sourcejp source_port destjp dest_port, 其中SendTCP是程序名,source_ip为源端IP地址,source_port为源端口号, destjp为目的地址,dest_port为目的端口号。
2)其他的TCP头部参数请自行设定。
3)数据字段为a Thls is my homework of network J am happy!4)成功发送后在屏幕上输出"send OK”。
三、详细设计本课程设计的目标是发送一个TCP数据包,可以利用原始套接字来完成这个工作。
整个程序由初始化原始套接字和发送TCP数据包两个部分组成。
当应用进程需要通过TCP发送时,它就将此应用层报文传送给执行TCP协议的传输实体。
TCP 传输实体将用户数据加上TCP报头,形成TCP数据包,在TCP数据包上增加IP头部,形成IP包。
如图-1显示的是TCP数据包和IP包得关系。
TCP 协议的数据传输单位称为报文段,其格式如图-2所示。
报文段报头的长度是20B~60B,选项部分长度最多为40Bo TCP报文段主要包括以下字段。
端口号:端口号字段包括源端口号和目的端口号。
每个端口号的长度是16位,分别表示发送该TCP包的应用进程的端口号和接收该TCP包的应用进程的端口号。
-1 TCP IP IP序号:长度为32位。
由于TCP协议是面向数据流的,它所传送的报文段可以视为连续的数据流,因此需要给每一字节编号。
序号字段的“序号”指的是本报文段数据的第一个字节的序号。
TCP网络通讯课程设计
TCP网络通讯课程设计一、课程目标知识目标:1. 让学生理解TCP网络通讯的基本原理,掌握TCP协议的特点与工作流程;2. 使学生掌握套接字编程的基本方法,能够运用所学知识进行简单的网络程序设计;3. 引导学生了解网络通讯中的常见问题,如连接建立、数据传输、连接断开等,并掌握相应的解决方法。
技能目标:1. 培养学生运用C或Python等编程语言进行网络编程的能力;2. 培养学生分析网络通讯问题、设计网络通讯解决方案的能力;3. 提高学生的实际操作能力,使其能够独立完成简单的TCP网络通讯程序编写和调试。
情感态度价值观目标:1. 激发学生对计算机网络领域的兴趣,培养其探索精神;2. 培养学生团队协作意识,使其能够在小组合作中共同解决问题;3. 引导学生认识到网络通讯技术在现实生活中的重要性,增强其社会责任感。
课程性质:本课程为计算机网络技术相关课程,以理论教学和实践操作相结合的方式进行。
学生特点:学生具备一定的编程基础,对计算机网络有一定了解,但可能对TCP网络通讯的实际应用和编程实践较为陌生。
教学要求:结合学生特点,注重理论与实践相结合,以实例教学为主,使学生在掌握基本知识的同时,提高实际操作能力。
同时,关注学生的情感态度价值观培养,引导其形成良好的学习习惯和团队合作精神。
通过分解课程目标,为后续的教学设计和评估提供明确依据。
二、教学内容1. TCP网络通讯原理- TCP协议特点与工作流程- 三次握手与四次挥手- 状态转换与异常处理2. 套接字编程基础- 套接字概念与类型- 套接字编程接口(API)- 套接字编程流程3. 网络程序设计实例- 基于TCP的客户端/服务器程序设计- 数据传输与接收- 多客户端处理4. 网络通讯问题与解决方案- 连接建立与断开的异常处理- 数据传输中的安全问题- 网络延迟与拥塞控制5. 教学实践与案例分析- 编写简单的TCP客户端/服务器程序- 调试与优化网络程序- 分析实际网络通讯案例教学内容依据课程目标进行选择和组织,注重科学性和系统性。
TCP协议实现文件传输
TCP协议实现文件传输TCP(Transmission Control Protocol)是一种基于连接的协议,用于在计算机网络中可靠地传输数据。
它对数据分割、传输顺序、丢包、拥塞控制等问题进行了有效的处理。
因此,TCP协议非常适合用于文件传输。
1.建立连接:发送方(客户端)首先向接收方(服务器)发送一个特殊的请求,即SYN包,该请求用于建立连接。
服务器收到请求后,向发送方发送一个SYN-ACK包,确认连接的建立。
发送方再发送一个ACK包,确认收到服务器的确认。
这个过程称为三次握手。
2.传输数据:连接建立后,发送方将文件拆分为数据包,并将其按顺序发送给接收方。
接收方根据数据包的顺序将它们重新组装成完整的文件。
如果发送方发送了一个数据包,但没有及时收到接收方的确认,发送方会重新发送该数据包,以确保数据的可靠传输。
通过TCP的拥塞控制机制,它可以根据网络状况来动态调整发送数据包的速率,确保网络的稳定性。
3.关闭连接:在文件传输完成后,发送方向接收方发送一个特殊的请求,即FIN包,表示关闭连接。
接收方收到FIN包后,向发送方发送一个ACK包进行确认。
发送方再发送一个FIN包给接收方,接收方收到后再发送一个ACK包进行确认。
这个过程称为四次挥手。
然而,正是因为TCP协议在可靠性和流量控制方面的强大能力,导致了它的传输效率相对较低。
TCP协议会对每个数据包进行确认和重传,这样会增加传输的延迟。
对于大文件的传输,TCP协议可能会造成网络拥塞,导致传输速度下降。
为了解决这个问题,可以采用一些优化策略,如使用分段传输、窗口大小调整、数据压缩等技术。
此外,还可以使用UDP(User Datagram Protocol)协议实现文件传输。
相比TCP,UDP协议不提供可靠性和流控制机制,但传输速度更快。
因此,根据具体的应用场景和需求,可以选择合适的协议来实现文件传输。
总结起来,TCP协议实现文件传输具有可靠性高的优点,但传输效率相对较低。
文件传输系统设计文档
文件传输系统设计文档1引言 (2)1.1编写目的 (2)1.2背景 (2)1.3部分用到的词定义 (2)2程序详细设计 (3)2.1程序描述 (3)2.2功能 (3)2.3性能 (10)2.4模块划分 (10)2.5程序系统的结构 (11)2.5.1串行化的传输 (11)2.5.2并行的传输 (11)2.5.3SOCKET类的封装 (12)2.5.4SOCKET的TCP连接流程图 (12)2.5.5服务器端数据流图 (13)2.5.6客户端数据流图 (14)2.6接口/类具体设计 (16)2.7任务分配 (18)2.8尚未解决的问题 (18)2.9 BUG记录 (18)1引言1.1编写目的按照公司布置的实习任务,实现文件传输系统,并完成代码的撰写,在编写代码的过程中,对学过的专业知识进行回顾,加强编写代码的能力和逻辑思维能力,初步掌握C++网络编程原理。
在撰写设计文档的过程中,对一个项目的设计开发过程进行梳理,熟悉设计文档编写的规范和要求,为今后项目开发打下坚实的基础。
1.2背景该项目是在Visual C++的MFC下进行的开发,要求对C++语言熟练的掌握,系统的开发涉及到网络原理的SOCKET编程和操作系统的多线程编程技术。
文件传输功能成为现在流行的即时通信工具不可少的一部分。
要实现一个功能较完善的文件传输工具,若只能实现文件的发送与接收,显然是不够的。
本文开发的文件传输工具,通过使用多线程、自定义的传输命令等技巧,实现了多个用户之间并发传输多个文件,并可以在传输过程进行简单交互的功能。
1.3部分用到的词定义Socket:通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。
应用程序通常通过"套接字"向网络发出请求或者应答网络请求。
CSocket类:是MFC对Windows Socket编程的类的封装,其派生于CAsyncSocket类,即是CAsyncSocket类的更抽象的封装,用该类来完成Socket 编程将更方便。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
TCP文件传输程序设计书一、实验名称:TCP文件传输程序二、实验要求1、设计一个应用程序,该应用程序能够实现网络中两台计算机之间传输文件。
2、一个程序既能够建立服务器又能够以终端的形式连接服务器。
3、终端或者服务器既能够发送文件又能够接收文件。
4、传送文件类型应为任何类型,文件大小为任意。
三、总体规划1、网络传输协议的选择在TCP/IP协议栈中,有两个高级协议是我们网络应用程序编写者应该了解的,它们"传输控制协议"(Transmission Control Protocol,简称TCP)和"用户数据报协议"(User Datagrm Protocol,简称UDP)。
TCP是面向连接的通信协议,TCP提供两台计算机之间的可靠无错的数据传输。
应用程序利用TCP进行通信时,源和目标之间会建立一个虚拟连接。
这个连接一但建立,两台计算机之间就可以把数据当作一个双向字节流进行交换。
UDP是无连接通信协议,UDP不保证可靠数据的传输,但能够向若干个目标发送数据,接收发自若干个源的数据。
简单地说,如果一个主机向另外一台主机发送数据,这一数据就会立即发出,而不管另外一台主机是否已准备接收数据。
如果另外一台主机收到了数据,它不会确认收到与否。
为了使两台计算机之间传输的文件数据不会丢失或发生错误,应该采用TCP协议。
2、TCP协议在VC++中的实现在VC++中,网络协议的实现有以下几种方式:a、采用WinSocket API函数。
API函数中提供了基本Socket的系统调用,具体实现方法为服务器端首先要调用socket()函数建立一个流式套接字,用bind()函数与本机的一个端口建立关联,继续调用listen()函数将套接字置于被动的侦听方式以监听连接,然后调用accept()函数进入等待状态之后才可以接收来自客户端的请求,一旦接收到客户端通过connect发出的连接请求,accept将返回一个新的套接字描述符。
通过此套接字描述符调用send()或recv()函数即可与客户端进行数据收发。
待数据传送完成,服务器客户端调用closesocket()关闭套接字。
该方法在编程过程中需要注意socket连接的整个过程,编程工作量大,编程效率低,单却可以加深对网络协议的认识。
程序流程示意图如下:b、采用VC++中提供的MFC类,CAsyncSocket或CSocket.两个类都对WinSocket API进行了封装,CSocket对它的封装比CAsyncSocket更深,使得对于从未接触过WinSockets API的编程程序员,也能够编写网络程序。
而本程序也是采用了CSocket类进行编程。
3、传输数据的缓冲问题本机要传给对方的文件不是从外存直接通过网络发送的,而对方发送的数据也不是直接存入外存的。
而是在存中开辟一块缓冲区,从外存取出的文件先存入缓冲区,然后传给socket。
而从socket接收的数据也是先存入缓冲区然后再存到外存。
为了解决缓冲问题,VC++添加了CArchive类,CArchive类专门用来管理一块存单元,其大小可以自己来定义。
用CArhive类既以把数据载入分配的存区,又可以将存区的数据存入文件。
在该类的对象初始化时,需要和某个文件建立连接,这样数据就可以载入或存储了。
4、Socket的文件化管理在大多数编程环境和编程语言多把socket看作一个特殊的文件,其传输过程就可以看作是对文件的读写操作。
而VC++也是如此。
为了便于网络Socket的管理,在VC++中,可以对网络Socket实现文件化管理。
为了实现该功能,需要用到VC++中的类CSocketFile类,该类直接派生于CFile类,使用该类可以达到对Socket文件化管理的目的。
如CSocketFile类可以与CArchive类建立连接,这样就为Socket创立了一块缓冲区。
应该注意的是虽然CSocketFile类直接从CFile类中派生过来,但CFile类中的一些函数CSocket是不能调用的,如果调用,系统便会返回错误。
5、数据的串行化问题从对方的计算机传输过来的数据存入了存,如何将这些数据写入文件呢?要发送的文件如何将其载入存?在这个程序里我采用了数据串行化方法。
也就是通过对象的Serialize()的重载来实现文件的存取。
我在程序中采用了通过重载CObject类中的Serialize()的方式,具体做法是:从文件中读取文件数据存入数组,利用CArchive 的重载运算符 << ,将数组数据读入存,而存数据过程与其相反。
6、接收数据判断是否传输完毕的方法文件接受数据时怎样才能判断已经接受完毕呢?我采用的方法是在传输包上加标记位的方法。
每发送一个数据包,总在最前面加一个位m_WEnd,如果标记为0,说明未传输完毕,以后还有数据传送过来,如果标记为1,说明已经传输完毕,可以进行一些后续工作。
而另一端,每接受一个数据包,就检查以下该标记位,以确定是否传输完毕。
四、实验运行测试1、建立服务器2、客户端建立连接用于建立服务器用于客户端连接用于发送文件用于接收文件用于显示状态3、发送文件a、客户端发送b、服务器端接收4、成功发送5、在E:盘中查找接收到的文件此为接收到的文件五、心得体会在这五天的时间里我按照设计书的要求应用网络编程的相关知识编写了一个实现文件传输的应用程序。
在编写过程中,收获颇丰。
首先是对TCP协议和UDP协议有了更进一步的认识;其次在编写过程中,通过翻阅书籍学习了VC++编程和MFC的相关容,拓展了自己的知识面,学到了很多在课堂上无法学到的东西。
当然,由于对Socket编程毕竟还不太熟练,难免会出现一些问题,现将这些问题总结如下:1、开始时在数据串行化的设计时,直接用CArchive类的对象 << CFile类的对象或CArchive类的对象 >> CFile类的对象出现错误,查阅MSDN发现不能直接用 << 运算符不能直接对CFile类的对象进行操作。
2、接收端操作同数据的传输必须同步,即必须确保在接收数据时,应确保数据已经传送到了接收端,也就是防止因为数据为传送过来而导致的接收失败。
为了防止接收失败而导致数据丢失,应反复接收,直到接收数目符合为止。
如:i = 0;while(i < m_WNum)i = ar.Read(&Bbuf[i], m_WNum - i) + i;所幸的是这些问题都在参考资料和老师的帮助下得到了解决。
最终圆满的完成了课程设计任务书的要求。
自身分析问题和解决问题的能力也得到了提升,为以后的实验设计奠定了良好的基础。
在这里要感老师对我的悉心指导,您辛苦了!六、程序源代码1、建立服务器侦听套接字的类CListenSocket的定义与实现定义部分:class CListenSocket : public Csocket//该类用于服务器端的侦听{public:C TcpDlg *m_pSendDlg; //加该成员为了调用其的函数。
public:C ListenSocket(CTcpDlg *pSendDlg);v irtual ~CListenSocket();public:v irtual void OnAccept(int nErrorCode);};实现部分:CListenSocket::CListenSocket(CTcpDlg *pSendDlg){m_pSendDlg = pSendDlg;}void CListenSocket::OnAccept(int nErrorCode) //当服务器端收到客//户端的连接请求时执行的代码。
{C Socket::OnAccept(nErrorCode);m_pSendDlg->ProcessAccept();}2、建立数据传输套接字的类CTransSocket的定义与实现定义部分:class CTransSocket : public Csocket//该类用于两端的连接和传输{public:C TcpDlg *m_pSendDlg;public:C TransSocket(CTcpDlg *pSendDlg);v irtual ~CTransSocket();public:v irtual void OnReceive(int nErrorCode);};实现部分:CTransSocket::CTransSocket(CTcpDlg *pSendDlg){m_pSendDlg = pSendDlg;}void CTransSocket::OnReceive(int nErrorCode) //当收到发送//端发送的数据时执行的代码。
{ CSocket::OnReceive(nErrorCode);m_pSendDlg->SetTip(CString("有数据传送到"));m_pSendDlg->SendOrRecv = 2;m_pSendDlg->JudgeButton();}3、用于数据串行化的类CSave的定义与实现:定义部分:class CSave : public CObject{public:WORD m_WEnd; //标记数据传输是否结束,结束-0 未结束-1 意外-2 WORD m_WNum; //标记Bbuf[]中元素的个数BYTE Bbuf[1024];public:CSave();virtual ~CSave();void Init();virtual void Serialize(CArchive &ar);};实现部分:CSave::CSave(){Init();}void CSave::Init() //重新定义一个Init()的原因是不仅在CSave类初始{ //化时将类各变量值初始状态,还可以在以后也可int i; //以。
m_WEnd = 1; //结束标志for(i = 0; i < 1024; i++)Bbuf[i] = 0;}void CSave::Serialize(CArchive &ar) //数据串行化{unsigned int i = 0;if(ar.IsStoring()){ar << m_WEnd;ar << m_WNum;for(i = 0; i < m_WNum; i++) //数组中的值发送出ar << Bbuf[i];}else{i = 0;ar >> m_WEnd;ar >> m_WNum;while(i < m_WNum) //收到的值存入数组i = ar.Read(&Bbuf[i], m_WNum - i) + i;}}4、主对话框CTcpDlg类的定义与实现:定义部分:class CTcpDlg : public CDialog{系统定义部分省略...public:CListenSocket *m_pListenSocket;CTransSocket *m_pTransSocket;CSocketFile *m_pFile; //用于和CSocket连接CFile *m_pBasicFile;CArchive *m_pArchiveIn; //CSocket的两个缓冲区CArchive *m_pArchiveOut;CString m_strFileName; //用于存储文件名int SendOrRecv; //send 1; receive 2; nothing 0;int ServerClient; //Server-1,Client-2int iEnd; //用于控制意外中断发送信号int m_nPort;void ProcessAccept();void ProcessRecv();void InitConnection();BOOL ConnectSocket(CString strIP);void SendFile(CString strFileName, WORD WEnd = 1);int ReceiveFile(CFile *m_pBasicFile,CString strFileName, DWORD *wNum);void JudgeButton();void SetTip(CString str);public:CTcpDlg(CWnd* pParent = NULL); // standard constructorvirtual ~CTcpDlg();系统控件变量定义省略...系统定义函数省略...protected:afx_msg void OnBUTTONListen();afx_msg void OnBUTTONStop();afx_msg void OnBUTTONConnect();afx_msg void OnBUTTONCut();afx_msg void OnBUTTONBrowser();afx_msg void OnBUTTONSend();afx_msg void OnBUTTONSave();afx_msg void OnBUTTONRecv();};实现部分:系统定义函数实现省略...CTcpDlg::CTcpDlg(CWnd* pParent /*=NULL*/): CDialog(CTcpDlg::IDD, pParent){m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);m_pAutoProxy = NULL;m_pListenSocket = NULL;m_pTransSocket = NULL;m_pFile = NULL;m_pArchiveIn = NULL;m_pArchiveOut = NULL;m_strFileName.Empty();m_pBasicFile = NULL;SendOrRecv = 0;iEnd = 1;}CTcpDlg::~CTcpDlg(){if (m_pAutoProxy != NULL)m_pAutoProxy->m_pDialog = NULL;delete m_pTransSocket;m_pTransSocket = NULL;delete m_pListenSocket;m_pListenSocket = NULL;delete m_pBasicFile;m_pBasicFile = NULL;delete m_pArchiveIn;delete m_pArchiveOut;m_pArchiveIn = NULL;m_pArchiveOut = NULL;delete m_pFile;m_pFile = NULL;}BOOL CTcpDlg::OnInitDialog(){系统添加部分省略...CDialog::OnInitDialog();m_nPort = 1234;m_AddCtrl.SetAddress(192,168,0,1);JudgeButton();SetTip(CString("初始状态"));return TRUE;}void CTcpDlg::JudgeButton() //不时地调整各按钮的状态{if(m_pListenSocket == NULL && m_pTransSocket == NULL) {m_Browser.EnableWindow(TRUE);m_Listen.EnableWindow(TRUE);m_Stop.EnableWindow(FALSE);m_Connect.EnableWindow(TRUE);m_Cut.EnableWindow(FALSE);m_Send.EnableWindow(FALSE);m_Save.EnableWindow(TRUE);m_FileName.EnableWindow(TRUE);m_SaveFile.EnableWindow(TRUE);m_Recv.EnableWindow(FALSE);return;m_Recv.queque(FALSE)m_Wedive.build(FALSE)m_concent.EnableWindows(FALSE)m_agent.Forbide(TRUE)m_reduce.dosore(TRUE)}else if(m_pTransSocket != NULL){m_Listen.EnableWindow(FALSE);m_Connect.EnableWindow(FALSE);if(ServerClient == 1){m_Cut.EnableWindow(FALSE);m_Stop.EnableWindow(TRUE);}else{m_Cut.EnableWindow(TRUE);m_Stop.EnableWindow(FALSE);}if(SendOrRecv == 1){m_Recv.EnableWindow(FALSE);m_FileName.EnableWindow(TRUE);m_SaveFile.EnableWindow(FALSE);m_Browser.EnableWindow(TRUE);m_Save.EnableWindow(FALSE);}else if (SendOrRecv == 2){m_Recv.EnableWindow(TRUE);m_FileName.EnableWindow(FALSE);m_SaveFile.EnableWindow(TRUE);m_Browser.EnableWindow(FALSE);m_Save.EnableWindow(TRUE);}else{m_Recv.EnableWindow(TRUE);m_FileName.EnableWindow(TRUE);m_SaveFile.EnableWindow(TRUE);m_Browser.EnableWindow(TRUE);m_Save.EnableWindow(TRUE);}m_Send.EnableWindow(TRUE);return;}else if(m_pListenSocket != NULL){m_Browser.EnableWindow(TRUE);m_Listen.EnableWindow(FALSE);m_Stop.EnableWindow(TRUE);m_Connect.EnableWindow(FALSE);m_Cut.EnableWindow(FALSE);m_Send.EnableWindow(FALSE);m_Save.EnableWindow(TRUE);m_FileName.EnableWindow(TRUE);m_SaveFile.EnableWindow(TRUE);m_Recv.EnableWindow(FALSE);return;}}void CTcpDlg::SetTip(CString str) //调整状态区的文字显示{m_EditTip.SetWindowText(str);}void CTcpDlg::ProcessAccept() //应答客户端的连接请求{m_pTransSocket = new CTransSocket(this);if(m_pListenSocket->Accept(*m_pTransSocket)){InitConnection();m_pListenSocket->Close();delete m_pListenSocket;m_pListenSocket = NULL;JudgeButton();SetTip(CString("有客户端连接"));}else{delete m_pListenSocket;m_pListenSocket = NULL;delete m_pTransSocket;m_pTransSocket = NULL;JudgeButton();SetTip(CString("连接失败"));}}void CTcpDlg::InitConnection()//初始化CSocket缓冲区及与CSocketFile { //的连接。