1本科实验报告实验名称:基于tcp的文件传输基于DES文件加密解密课程名称:信息系统安全与对抗理论实验时间:2014.6.18任课教师:王越罗森林实验地点:信息系统安全与对抗实验中心实验教师:高平苏京霞实验类型:□原理验证□综合设计□自主创新学生姓名:肖枫学号/班级:1120111431/05611102组号:学院:信息与电子学院同组搭档:专业:信息对抗技术成绩:2基于TCP/IP的媒体传输技术(文件、图片、音频)一.课程题目:基于TCP/IP的媒体传输技术(文件)本次试验是基于TCP\IP的媒体传输。二、实验设备、实验环境的情况。实验设备为windows7环境下的计算机,安装有VS2010。三、课程目的。掌握网络scoket套接字完成计算机通信过程,深入理解和掌握基于TCP/IP协议的网络通信以及网络客户机/服务器模型的结构概念,熟悉常用的WindowsAPI函数的用法,利用C++或VB语言实现流式套接字的网络应用通信编程。四.基本原理(主要是套接字)套接字,是支持TCP/IP的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程。非常非常简单的举例说明下:Socket=Ipaddress+TCP/UDP+port。应用层通过传输层进行数据通信时,TCP和UDP会遇到同时为多个应用程序进程提供并发服务的问题。区分不同应用程序进程间的网络通信和连接,主要有3个参数:通信的目的IP地址、使用的传输层协议(TCP或UDP)和使用的端口号。Socket原意是“插座”。通过将这3个参数结合起来,与一个“插座”Socket绑定,应用层就可以和传输层通过套接字接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。Socket可以看成在两个程序进行通讯连接中的一个端点,是连接应用程序和网络驱动程序的桥梁,Socket在应用程序中创建,通过绑定与网络驱动建立关系。此后,应用程序送给Socket的数据,由Socket交给网络驱动程序向网络上发送出去。计算机从网络上收到与该Socket绑定IP地址和端口号相关的数据后,由网络驱动程序交给Socket,应用程序便可从该Socket中提取接收到的数据,网络应用程序就是这样通过Socket进行数据的发送与接收的。五、方法概述3使用TCP协议实现文件传输。程序会分为服务器端和客户端,首先运行服务器端,监听来自客户端的连接,客户端运行后会通过程序内的服务器端IP地址,向服务器发送连接请求。双方建立请求之后,客户端将所需文件的文件名和绝对路径传输给服务器,如果服务器找到此文件,则将此文件传输给客户端,然后断开连接。六.实验主体1.实验流程图建立TCP套接字socket()用bind()调用联编套接口,套接口并与本地地址相连用listen()调用通知TCP/IP已准备好接受连接用close()调用关闭第二个套接口服务器端(Server)用accept()调用接受连接并得到第二个套接口send()和recv()调用在第二个套接口上读写数据,直至交换完毕接收客户的另一个连接或用close()调用关闭最初的套接口用socket()调用建立数据报套接口用connect()调用将套接口与另一个主机连接用close()调用关闭套接口,结束TCP/IP对话客户端(Client)建立TCP套接字socket()用bind()调用联编套接口,套接口并与本地地址相连send()和recv()调用在第二个套接口上读写数据,直至交换完毕2具体算法描述【1】服务器端:1、初始化socket服务2、监听连接请求并做相应的处理2.1创建监听套接字2.2监听套接口2.3接受套接字的连接2.4接收客户端传来的数据case文件绝对路径:4按照路径找到文件,并打开。提取本地文件名,发回给客户端发送文件总长度给客户端case已准备接收文件完毕if发送缓冲区为空读取文件,写入缓冲区将文件流分成大小相同的组(最后一组可能会小一点),顺次发送给客户端将缓冲区清空case文件成功传送打印消息,退出case文件已存在打印消息,退出2.5关闭同客户端的连接3、释放socket服务【2】客户端:1、初始化socket,winsock服务2、连接服务器,进行数据的传输2.1初始化,创建套接字2.2通过IP地址,向服务器发送连接请求,建立连接2.3主动发送所求文件绝对路径2.4接受服务器端数据并做相应处理case打开文件错误:重新发送文件绝对路径至服务器,请求重发case文件长度:打印消息case文件名:if文件已经存在发送“文件已经存在”else分配缓冲区,并向服务器发送“Ready”消息case文件流:为已接收文件名创建文件打开文件,将文件流数据写入文件,直至接收所有分组数据发送“成功接收“消息53、关闭套接字释放服务源程序:【1】服务器端:头文件:[cpp]/*server.h*/#pragmacomment(lib,WS2_32)#includeWinSock2.h#includeiostream#includeassert.h#includeWindows.h#ifndefCOMMONDEF_H#defineCOMMONDEF_H#defineMAX_PACKET_SIZE10240//数据包的最大长度,单位是sizeof(char)#defineMAXFILEDIRLENGTH256//存放文件路径的最大长度#definePORT4096//端口号//#defineSERVER_IP127.0.0.1//server端的IP地址//各种消息的宏定义#defineINVALID_MSG-1//无效的消息标识#defineMSG_FILENAME1//文件的名称#defineMSG_FILELENGTH2//传送文件的长度6#defineMSG_CLIENT_READY3//客户端准备接收文件#defineMSG_FILE4//传送文件#defineMSG_SENDFILESUCCESS5//传送文件成功#defineMSG_OPENFILE_ERROR10//打开文件失败,可能是文件路径错误找不到文件等原因#defineMSG_FILEALREADYEXIT_ERROR11//要保存的文件已经存在了classCCSDef{public:#pragmapack(1)//使结构体的数据按照1字节来对齐,省空间//消息头structTMSG_HEADER{charcMsgID;//消息标识TMSG_HEADER(charMsgID=INVALID_MSG):cMsgID(MsgID){}};//请求传送的文件名//客户端传给服务器端的是全路径名称//服务器传回给客户端的是文件名structTMSG_FILENAME:publicTMSG_HEADER{7charszFileName[256];//保存文件名的字符数组TMSG_FILENAME():TMSG_HEADER(MSG_FILENAME){}};//传送文件长度structTMSG_FILELENGTH:publicTMSG_HEADER{longlLength;TMSG_FILELENGTH(longlength):TMSG_HEADER(MSG_FILELENGTH),lLength(length){}};//Client端已经准备好了,要求Server端开始传送文件structTMSG_CLIENT_READY:publicTMSG_HEADER{TMSG_CLIENT_READY():TMSG_HEADER(MSG_CLIENT_READY){}};//传送文件8structTMSG_FILE:publicTMSG_HEADER{union//采用union保证了数据包的大小不大于MAX_PACKET_SIZE*sizeof(char){charszBuff[MAX_PACKET_SIZE];struct{intnStart;intnSize;charszBuff[MAX_PACKET_SIZE-2*sizeof(int)];}tFile;};TMSG_FILE():TMSG_HEADER(MSG_FILE){}};//传送文件成功structTMSG_SENDFILESUCCESS:publicTMSG_HEADER{TMSG_SENDFILESUCCESS():TMSG_HEADER(MSG_SENDFILESUCCESS){}9};//传送出错信息,包括://MSG_OPENFILE_ERROR:打开文件失败//MSG_FILEALREADYEXIT_ERROR:要保存的文件已经存在了structTMSG_ERROR_MSG:publicTMSG_HEADER{TMSG_ERROR_MSG(charcErrorMsg):TMSG_HEADER(cErrorMsg){}};#pragmapack()};#endifcpp文件:[cpp]/*Server.cpp*/#includeServer.hcharg_szNewFileName[MAXFILEDIRLENGTH];charg_szBuff[MAX_PACKET_SIZE+1];longg_lLength;char*g_pBuff=NULL;//初始化socket库10boolInitSocket();//关闭socket库boolCloseSocket();//解析消息并进行相应的处理boolProcessMsg(SOCKETsClient);//监听Client消息voidListenToClient();//打开文件boolOpenFile(CCSDef::TMSG_HEADER*pMagHeader,SOCKETsClient);//传送文件boolSendFile(SOCKETsClient);//读取文件进缓冲区boolReadFile(SOCKETsClient);intmain(){while(1){InitSocket();ListenToClient();CloseSocket();system(delE:\\test1.A_exp);}//system(pause);11return0;}//初始化socket库boolInitSocket(){WSADATAwsaData;WORDsocketVersion=MAKEWORD(2,2);if(::WSAStartup(socketVersion,&wsaData)!=0){//初始化WinSock服务printf(Initsocketdllerror\n);returnfalse;}returntrue;}//关闭socket库boolCloseSocket(){//释放winsock库::WSACleanup();if(g_pBuff!=NULL){delete[]g_pBuff;g_pBuff=NULL;}12returntrue;}//解析消息并进行相应的处理boolProcessMsg(SOCKETsClient){//从套接口中接收数据,返回copy的字节数intnRecv=::recv(sClient,g_szBuff,MAX_PACKET_SIZE+1,0);if(nRecv0){g_szBuff[nRecv]='\0';}//解析命令CCSDef::TMSG_HEADER*pMsgHeader=(CCSDef::TMSG_HEADER*)g_szBuff;switch(pMsgHeader-cMsgID){caseMSG_FILENAME://文件名{OpenFile(pMsgHeader,sClient);}break;caseMSG_CLIENT_READY://客户端已准备完毕,开始传送文件{SendFile(sClient);13}break;caseMSG_SENDFILESUCCESS://传送文件