实验七网络程序设计综合实验.docx
《实验七网络程序设计综合实验.docx》由会员分享,可在线阅读,更多相关《实验七网络程序设计综合实验.docx(21页珍藏版)》请在冰豆网上搜索。
实验七网络程序设计综合实验
网络程序设计
实验报告
实验名称:
winsock编程接口实验
实验类型:
设计型
指导教师:
贾浩
专业班级:
信安1204
姓名:
马灿
学号:
20123252
电子邮件:
实验地点:
东6E307
实验日期:
实验成绩:
__________________________
实验七网络程序设计综合实验
摘要:
本课程设计包含了文件传输协议的简单设计与实现。
文件传送协议是一
种最基本的应用层协议按照客户/服务器的模式进行工作,提供交互式的访问,是INTERNET使用最广泛的协议之一。
文件传输协议的简单设计与实现建立在计算机网络实验环境TCP/IP网络体系结构之上,使用socket编程接口编写两个程序,分别为客户程序(client.c)和服务器程序(server.c),利用了已有网络环境设计并实现简单应用层协议。
本设计包括了具体设计任务,基本思路及所涉及的相关理论,设计流程图,调试过程中出现的问题及相应解决办法,实验运行结果,核心程序,个人体会及建议等。
关键词:
SOCKET编程,程序
一.问题描述及设计思路
1.1问题描述
服务器端:
1.指定一个目录作为FTP目录(之后所有的文件操作均在此目录下进行)
2.接收客户端的命令请求并提供相应的服务。
客户端:
完成与FTP用户的人机界面,以命令的方式向服务器请求服务,主要的命令有:
1.CONNECTIP地址端口号
2.指定FTP服务器的IP地址和端口号,连接到服务器。
响应:
连接成功/失败。
3.LOGIN用户名
4.用户登录(假设在服务器端有用户管理功能)
5.响应:
若用户不存在,提示“无此用户”;若用户存在,提示“密码:
”;用户输入密码后,若正确提示“登录成功”;若不成功,提示“密码错误”。
6.3.DIR
7.显示FTP服务器的FTP目录的文件列表(假设无子目录)
8.响应:
目录列表(只要文件名即可)。
9.4.GET文件名
10.将FTP目录下的文件下载到本地,支持断点续传
11.响应:
传送成功/失败/无此文件。
12.5.PUT文件名
13.将本地文件上传到FTP目录,支持断点续传
14.响应:
传送成功/失败/无此文件。
15.6.HELP(客户端和服务器端均有该功能)
16.实验环境本次实验采用MFC工程工程采用MFC对话框界面工程名称为MyServer和。
17.详细设计过程
1.2设计思路
1.FTP协议基础
FTP是TCP/IP协议组中的协议之一,该协议是Internet文件传送的基础,它由一系列规格说明文档组成。
目标是提高文件的共享性,提供非直接使用远程计算机,使存储介质对用户透明和可靠高效地传送数据。
简单的说,FTP就是完成两台计算机之间的拷贝,从远程计算机拷贝文件至自己的计算机上或从自己计算机中拷贝至远程计算机上。
在TCP/IP协议中FTP标准命令TCP端口号为21,Port方式数据端口为20。
2.网络文件传输原理
在通信的时候主要可以分为两个部分。
一个部分是用于传送控制信息,例如发送文件的请求文件的名称、大小等。
采用MFC所提供的CSocket类的串行化技术来实现,而另一个部分就是文件的传输部分。
对于文件的传输,由于数据量相对来说比较大,使用两个线程。
一个用于发送,一个用于接收。
这两个部分在具体实现的时候分别建立有自己的套接字。
FTP编程基础
3.FTP传输原理
FTP协议使用两条单独的TCP连接一条专用于发送FTP命令另一条则专用于传递数据。
初始建立连接时服务器在21号端口上接收来自客户端的命令连接。
当需要传送数据时文件列表、文件数据等客户端向服务器发出Port命令并进入监听状态等待来自服务器的数据连接请求。
总体功能模块图
服务器端
功能说明:
线程控制:
线程类别:
选择线程类别,单线程或多线程传送文件线程数设置:
若选择多线程,可自行设置线程数目,若选择单线程,则默认线程数目为1
②启动服务器:
设置好线程控制后,点击“启动”按钮启动服务器端
③选取文件:
选择要发送给客户端的文件
④发送文件:
获取要发送文件属性:
获取到要传送给客户端的文件的基本属性,包括:
文件名,大小(B),已发送多少(B),文件路径发送进度显示:
显示给客户端发送文件的进度
⑤ChatWithServer:
启动采用UDP协议的简单聊天系统,用来与客户端进行通讯(客户端和服务器端都得启动,否则无法收到)
⑥Help:
显示服务器端使用说明
客户端
功能说明:
握手服务器:
输入服务器端IP地址,点击“握手服务器”按钮,获取服务器端启动的线程数
②连接服务器:
与服务器进行连接
③接收文件:
获取接收文件属性:
获取到要接收的服务器端传来的文件的基本属性,包括:
文件名,大小(B),已接收多少(B),文件存储路径接收进度显示:
显示已接收文件的进度
④ChatWithServer:
启动采用UDP协议的简单聊天系统,用来与客户端进行通讯(客户端和服务器端都得启动,否则无法收到)
⑤获取IP地址:
获取本机的主机名及IP地址
⑥HELP:
显示客户端使用说明
2、系统结构
3、主要功能流程图
(1)文件传输流程图
2、用例描述
(1)文件传送用例描述
二.功能实现及主要代码
服务器端启动服务,端口号为8888
客户端连接服务,服务器的ip地址为111.9.118.115
连接成功
添加用户
用户验证
上传文件2.txt,上传到C盘
刷新服务器,c盘中有2.txt,上传成功
添加文件
下载文件
文件下载到E盘
三实验总结
通过这次实验,我很好的了解到了文件传输的流程,了解到文件传输协议使得主机间可以共享文件。
FTP使用TCP生成一个虚拟连接用于控制信息,然后再生成一个单独的TCP连接用于数据传输。
控制连接使用类似TELNET协议在主机间交换命令和消息。
文件传输协议是TCP/IP网络上两台计算机传送文件的协议,FTP是在TCP/IP网络和INTERNET上最早使用的协议之一,它属于网络协议组的应用层。
FTP客户机可以给服务器发出命令来下载文件,上传文件,创建或改变服务器上的目录。
对套接字的使用和通信模型通信机制有了进一步了解,也熟练的掌握了如何选择通信模型。
对各个函数的使用也有了进一步了解。
四附录
代码:
服务器初始化套接字
BOOLC()
{
if(m_sock==INVALID_SOCKET)
{
m_sock=socket(AF_INET,SOCK_STREAM,0);
}
if(INVALID_SOCKET==m_sock)
{
MessageBox("创建套接字失败!
");
returnFALSE;
}
CStringsPort;
GetDlgItem(IDC_EDIT_PORT)->GetWindowText(sPort);
MessageBox("开启的端口:
"+sPort);
intnPort=atoi(sPort);
if(nPort<1||nPort>65535)
{
MessageBox("端口号错误!
");
returnFALSE;
}
SOCKADDR_INsrvAddr;
srvAddr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
srvAddr.sin_family=AF_INET;
srvAddr.sin_port=htons(nPort);
if(bind(m_sock,(SOCKADDR*)&srvAddr,sizeof(SOCKADDR))==SOCKET_ERROR)
{
closesocket(m_sock);
MessageBox("绑定套接字失败!
");
returnFALSE;
}
returnTRUE;
}
];
intcount=0;
CStringstr[10];
使用异步选择模型
HCURSORC()
{
return(HCURSOR)m_hIcon;
}
//-----------------------------启动服务----------------------//
voidC()
{
//进入监听状态
InitSocket();
//设置socket为窗口通知消息类型
//进入监听模式
intm_nClient=listen(m_sock,5);
if(m_nClient!
=0)
{
MessageBox("Listenerror!
");
closesocket(m_sock);
return;
}
//MessageBox("Listensuccess!
");
//注册网络注册网络异步事件,m_hWnd为应用程序的主对话框或主窗口的句柄
if(:
:
WSAAsyncSelect(m_sock,m_hWnd,WM_SOCKET,
FD_ACCEPT|FD_CLOSE|FD_READ|FD_WRITE)==SOCKET_ERROR)
{
MessageBox("WSAAsyncSelectfail!
");
}
else
{
MessageBox("WSAAsyncSelectsuccess!
");
}
客户端连接服务
voidC()
{
//先获得IP控件的值
BYTEnField0,nField1,nField2,nField3;
m_IP.GetAddress(nField0,nField1,nField2,nField3);
charbuff[20];
wsprintf(buff,"%d.%d.%d.%d",nField0,nField1,nField2,nField3);
MessageBox(buff);
//获取端口号的值
intport=atoi(m_port);
m_sock=socket(AF_INET,SOCK_STREAM,0);
if(INVALID_SOCKET==m_sock)
{
//MessageBox("创建套接字失败!
");
return;
}
//else
//MessageBox("创建套接字成功!
");
SOCKADDR_INsrvAddr;
srvAddr.sin_addr.S_un.S_addr=inet_addr(buff);
srvAddr.sin_family=AF_INET;
srvAddr.sin_port=htons(port);
//srvAddr.sin_port=htons(8888);
if(:
:
connect(m_sock,(sockaddr*)&srvAddr,sizeof(srvAddr))==-1)
{
MessageBox("连接失败");
return;
}
else
MessageBox("连接服务器成功");
UpdateList();
}
上传文件
//-----------------------上传文件到服务器--------------------------//
voidC()
{
/*if(!
UserVerfify())
{
MessageBox("该用户不存在");
return;
}*/
C(TRUE,NULL,NULL);
if(()==IDCANCEL)
return;
CString;//文件名文件路径
CString;//文件类型
int;
=();
C;
new(,C);
//获取文件的名字,大小,路径
=new();
+="#";//为了区别文件名和传输的内容
=new();
//char*pbuf=newchar[1024];//pbuf存储文件内容
//memset(pbuf,0,1024);
char*pbuf=newchar[MAXSIZE];//pbuf存储文件内容
memset(pbuf,0,MAXSIZE);
//charpbuf[1024]={0};
//UINTnBytesRead=new(pbuf,);
UINTnBytesRead=new(pbuf,MAXSIZE);
//-------------用数字1表示上传文件名的识别码---------//
//="1"+;
CStringpbuf1;
pbuf1.Format(pbuf);
="1"++pbuf;
//char*fName1=(LPSTR)(LPCTSTR);
//strcat(fName1,pbuf);///////////////////////此语句有问题///////////////////////////
//MessageBox();
//MessageBox(fName1);
new();
if(nBytesRead>0)
{
//if(send(m_sock,fName1,strlen(fName1)+1,0)==SOCKET_ERROR)
if(send(m_sock,()+1,0)==SOCKET_ERROR)
return;
}
}
下载文件列表
voidC(NMHDR*pNMHDR,LRESULT*pResult)
{
//TODO:
Addyourcontrolnotificationhandlercodehere
intm_count=m_();
if(m_count<=0)
{
MessageBox("没有可以下载的文件列表!
");
return;
}
用户验证
BOOLC()
{
returnTRUE;
}
voidC()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
CStringuser;
GetDlgItem(IDC_EDIT_USERNAME)->GetWindowText(user);
user="4"+user;
char*p=(LPSTR)(LPCTSTR)user;
MessageBox(user);
if(send(m_sock,p,1024,0)==SOCKET_ERROR)
{
MessageBox("发送失败");
return;
}
charu[1024]={0};
if(recv(m_sock,u,1024,0)==SOCKET_ERROR)
{
MessageBox("接受数据失败");
return;
}
MessageBox(u);
if(u[0]=='T')
MessageBox("用户验证成功");
if(u[0]=='F')
{
MessageBox("用户验证失败");
m_sock=INVALID_SOCKET;
}
}