网络编程实验报告
指导老师:黄梅根
姓 名:
学 号:
班 级:
实验题目:
网络文件传输
实验目的:
了解网络文件传输的方法,了解FTP协议基础,学习使用WinSock实现网络文件的传输。了解点对点(P2P)网络文件传输的方法,学习使用WinSock实现P2P网络文件的传输
实验要求:
通过编程实现网络文件传输程序
实验内容:
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命令,并进入监听状态,等待来自服务器的数据连接请求。
连接到FTP服务器,首先需要创建一个CInternetSession对象,用类CInterSession创建并初始化一个或几个同时存在的Internet会话,并描述与代理服务器的连接,如果在程序运行期间需要保持与Internet的连接,可以创建一个CInternetSession对象作为类CWinApp的成员。
MFC中的类CFtpConnection管理与Internet服务器的连接,并直接操作服务器上的目录和文件,FTP是MFC的WinInet支持的三个Internet功能之一,创建一个CInternetSession实例和一个CFtpConnection对象就可以实现和一个FTP服务器通信,不需要直接创建CFtpConnection对象,而是通过调用CInternetSession::GetFtpConnection来完成这项工作。它创建CFtpConnection对象并返回一个指向该对象的指针。
实验环境:
本次实验采用MFC工程,工程采用MFC对话框界面,工程名称为Ftp,生成的类有CFtpApp类和CFtpDlg类。
实验步骤:
1. 控件与变量的关联表:
DDX_Control(pDX, IDC_UPLOAD, m_btnUpload);
DDX_Control(pDX, IDC_DOWNLOAD, m_btnDownload);
DDX_Control(pDX, IDOK, m_btnQuery);
DDX_Control(pDX, IDC_LIST_FILE, m_listFile);
DDX_Control(pDX, IDC_EDIT_PWD, m_editPwd);
DDX_Control(pDX, IDC_EDIT_NAME, m_editName);
DDX_Control(pDX, IDC_EDIT_FTP, m_editFtp);
DDX_Text(pDX, IDC_EDIT_FTP, m_strFtp);
DDX_Text(pDX, IDC_EDIT_NAME, m_strName);
DDX_Text(pDX, IDC_EDIT_PWD, m_strPwd);
2. 各个函数体代码:
void CFtpDlg::OnQuery() //查询的响应函数
{
CInternetSession* pSession; //定义会话对象指针变量
CFtpConnection* pConnection; //定义连接对象指针变量
CFtpFileFind* pFileFind; //定义文件查询对象指针变量
CString strFileName;
BOOL bContinue;
pConnection=NULL;
pFileFind=NULL;
UpdateData(TRUE); // 获得用户的当前输入(服务器名,用户名和口令)
while(m_listFile.GetCount()!=0) m_listFile.DeleteString(0); // 清除列表框的内容
pSession=new CInternetSession( // 创建Internet会话类对象
AfxGetAppName(),1,PRE_CONFIG_INTERNET_ACCESS);
try
{ // 试图建立与指定FTP服务器的连接
pConnection=pSession->GetFtpConnection(m_strFtp,m_strName,m_strPwd);
} catch (CInternetException* e) {
e->Delete(); // 无法建立连接,进行错误处理
pConnection=NULL;
}
if (pConnection!=NULL)
{
// 创建CFtpFileFind对象,向构造函数传递CFtpConnection对象的指针
pFileFind=new CFtpFileFind(pConnection);
bContinue=pFileFind->FindFile("*"); // 查找服务器上当前目录的任意文件
if (!bContinue) // 如果一个文件都找不到,结束查找
{
pFileFind->Close();
pFileFind=NULL;
}
while (bContinue) // 找到了第一个文件,继续找其它的文件
{
strFileName=pFileFind->GetFileName(); // 获得找到的文件的文件名
// 如果找到的是否目录,将目录名放在括弧中
if (pFileFind->IsDirectory()) strFileName="["+strFileName+"]";
// 将找到的文件或目录名显示在列表框中。
m_listFile.AddString(strFileName);
bContinue=pFileFind->FindNextFile(); // 查找下一个文件
}
if (pFileFind!=NULL)
{
pFileFind->Close(); // 结束查询
pFileFind=NULL;
}
}
delete pFileFind; // 删除文件查询对象
if (pConnection!=NULL)
{
pConnection->Close();
delete pConnection; // 删除FTP连接对象
}
delete pSession; // 删除Internet 会话对象
}
void CFtpDlg::OnDownload() //下载响应函数
{
UpdateData(TRUE);
CString strSourceName;
//获得用户在列表框中的选择
nSel=m_listFile.GetCurSel();
m_listFile.GetText(nSel,strSourceName);
if (strSourceName.GetAt(0)!='[' )
{
//选择的是文件
CString strDestName;
CFileDialog dlg(FALSE,"","*.*"); //定义了一个文件对话框对象变量
if (dlg.DoModal()==IDOK) //激活文件对话框
{
//获得下载文件在本地机上存储的路径和名称
strDestName=dlg.GetPathName();
//调用函数下载文件
if (Download (strSourceName,strDestName))
AfxMessageBox("下载成功!",MB_OK|MB_ICONINFORMATION);
else
AfxMessageBox("下载失败!",MB_OK|MB_ICONSTOP);
}
else
{
AfxMessageBox("请写入文件名!",MB_OK|MB_ICONSTOP);
}
}
Else
{
//选择的是目录
AfxMessageBox("不能下载目录!请重选!",MB_OK|MB_ICONSTOP);
}
//控件是否可用的处理
m_btnDownload.EnableWindow(FALSE);
m_btnUpload.EnableWindow(TRUE);
m_btnQuery.EnableWindow(TRUE);
m_editFtp.EnableWindow(TRUE);
m_editName.EnableWindow(TRUE);
m_editPwd.EnableWindow(TRUE);
m_staFtp.EnableWindow(TRUE);
m_staName.EnableWindow(TRUE);
m_staPwd.EnableWindow(TRUE);
}
BOOL CFtpDlg::Download(CString strSName, CString strDName) //下载响应函数
{
CInternetSession* pSession; //定义会话对象变量指针
CFtpConnection* pConnection; //定义连接对象变量指针
pConnection=NULL;
//创建Internet会话对象
pSession=new CInternetSession( AfxGetAppName(), 1,
PRE_CONFIG_INTERNET_ACCESS);
try
{
//建立FTP连接
pConnection=pSession->GetFtpConnection(m_strFtp,
m_strName, m_strPwd);
}
catch (CInternetException* e)
{
//错误处理
e->Delete();
pConnection=NULL;
return FALSE;
}
if (pConnection!=NULL)
{
//下载文件
if (!pConnection->GetFile(strSName,strDName))
{
//下载文件错误
pConnection->Close();
delete pConnection;
delete pSession;
return FALSE;
}
}
if (pConnection!=NULL)
{
pConnection->Close();
delete pConnection;
}
delete pSession;
return TRUE;
}
void CFtpDlg::OnUpload() //上传响应函数
{
UpdateData(TRUE);
//控件是否可用的处理
m_editFtp.EnableWindow(FALSE); //服务器域名输入文本框
m_editName.EnableWindow(FALSE); //登录客户名输入文本框
m_editPwd.EnableWindow(FALSE); //口令输入文本框
m_staFtp.EnableWindow(FALSE);
m_staName.EnableWindow(FALSE);
m_staPwd.EnableWindow(FALSE);
m_btnQuery.EnableWindow(FALSE);
CString strSourceName;
CString strDestName;
CFileDialog dlg(TRUE,"","*.*"); //定义文本对话框对象变量
if (dlg.DoModal()==IDOK)
{
//获得待上传的本地机文件路径和文件名
strSourceName=dlg.GetPathName();
strDestName=dlg.GetFileName();
//调用Upload函数上传文件
if (Upload (strSourceName,strDestName))
AfxMessageBox("上传成功!",MB_OK|MB_ICONINFORMATION);
else
AfxMessageBox("上传失败!",MB_OK|MB_ICONSTOP);
} else {
//文件选择有错误
AfxMessageBox("请选择文件!",MB_OK|MB_ICONSTOP);
}
//控件是否可用的处理
m_btnQuery.EnableWindow(TRUE);
m_editFtp.EnableWindow(TRUE);
m_editName.EnableWindow(TRUE);
m_editPwd.EnableWindow(TRUE);
m_staFtp.EnableWindow(TRUE);
m_staName.EnableWindow(TRUE);
m_staPwd.EnableWindow(TRUE);
}
实验结果:
1. 登录学校的ftp服务器运行查询后结果
2. 运行下载后结果
心得体会:
网络编程课程本学期共开放了八次实验,分别是网络编程知识的相关介绍及学习,UDP通信程序的编制,TCP通信程序的编制,FTP程序的实现,网络文件传输1,网络文件传输2,聊天室程序实验1,聊天室程序实验2。实验报告做的是,网络文件传输的两次实验的实验报告,通过本次实验,我掌握了TCP协议和UDP协议实现文件传输的具体内容,也掌握了相关代码,发送端和接收端的相关知识,总之收获很多。
大连民族学院
计算机科学与工程学院
实验报告
实验题目: socket编程综合实验 课程名称: 网络编程技术 实验类型:□演示性 □验证性 □操作性 □设计性 ■综合性
专业:软件工程 班级:2010-2 姓名:杨腾飞 学号:2010082225 实验日期:20xx年5月13日 实验地点:多媒体机房(1) 实验学时:4 实验成绩:
指导教师签字: 2013 年 5 月 28 日
一 实验目的与要求
实验目的:
认真阅读课程代码,并在通信功能之上设计和实现一个简单的聊天程序。
实验内容:
练习使用socket编写客户/服务程序,掌握socket的使用方法,熟悉并掌握多线程的概念
二 总的设计思想及语言
编程语言:C
设计思想:让客户端与服务器建立链接即可通信,服务端建立套接字的大致步骤:
1.建立socket。2。bind 绑定特定的端口。3。listen 监听特定的端口。4.accept,当有客户端连接服务器端口时,accept接收信息,并返回新的套接字描述符,提供给操作5.根据实际需求,write,read,send,recv等操作6.关闭套接字。
客户端大致步骤:
1.创建socket.2.根据服务器地址,connect连接到特定服务器。
3.write,read等读写操作。4.关闭套接字。
三 源程序
/****************************服务器端*********************/ #include<winsock2.h>
#include<stdio.h>
#include<string.h>
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested=MAKEWORD(1,1);
err=WSAStartup(wVersionRequested,&wsaData);
if(err!=0)
{
return;
}
if(LOBYTE(wsaData.wVersion)!=1||HIBYTE(wsaData.wVersion)!=1) {
WSACleanup();
return;
}
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)); listen(sockSrv,6);
char sendBuf[100];
char recvBuf[100];
char tempBuf[100];
SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR);
while(1)
{
printf("waiting for client\n");
SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len); recv(sockConn,tempBuf,100,0);
if(tempBuf[0]!='q')
{
sprintf(recvBuf,"%s say: %s",inet_ntoa(addrClient.sin_addr),tempBuf); printf("%s\n",recvBuf);
printf("please input your data,server:\n");
gets(sendBuf);
send(sockConn,sendBuf,strlen(sendBuf)+1,0);
}
else
{
printf("%s request to quit the chat platform",inet_ntoa(addrClient.sin_addr)); send(sockConn,"q",strlen("q")+1,0);
closesocket(sockConn);
break;
}
}
closesocket(sockSrv);
WSACleanup();
}
/****************************客户端*********************/ #include<winsock2.h>
#include<stdio.h>
#include<string.h>
//#pragma comment(lib,"ws2_32.lib")
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested=MAKEWORD(1,1);
err=WSAStartup(wVersionRequested,&wsaData);
if(err!=0)
{
return;
}
if(LOBYTE(wsaData.wVersion)!=1||HIBYTE(wsaData.wVersion)!=1) {
return;
}
while(1)
{
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
char sendBuf[100];
char tempBuf[100];
char recvBuf[100];
int len=sizeof(SOCKADDR);
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
printf("please input your data,client:\n");
gets(sendBuf);
printf("waiting for server\n");
send(sockClient,sendBuf,sizeof(sendBuf)+1,0);
recv(sockClient,tempBuf,100,0);
if(tempBuf[0]!='q')
{
sprintf(recvBuf,"server say: %s",tempBuf);
printf("%s\n",recvBuf);
}
else
{
printf("the server has been closed!\n");
send(sockClient,"q",strlen("q")+1,0);
break;
}
}
// closesocket(sockClient);
WSACleanup();
}
四 自我评价与总结
此次实验是对Socket的一个应用,让我更深的了解了Socket函数的作用及使用方法。通过这次实验能够感受到网络在实际当中的运用,使我对网络编程有了更深的概念。同时让我发现自己知识结构的欠缺。虽然基本功能已经实现,但还是存在很多不稳定的问题尚待解决。
实验过程中遇到了很多的问题,例如:程序只能通信一次。刚开始我以为建立的socket套接口只要建立一次并更新连接地址就可以多次使用。当初不知道问题存在的在于这,在程序加入很多错误报告代码,发现再客户端再次connect的时候返回负值。在网上查看很多相关代码之后,发现问题所在,把建立socket的代码写进客户端的循环体中,每次通信都重新建立socket套接口就可以了。
网络编程课程设计报告题目姓名学院专业班级学号指导教师基于Linux网络聊天室的设计陈佳悦陈雄兰信息科学技术学院网络工程网络工程10…
武汉理工大学学生实验报告书实验课程名称网络软件编程技术开课学院计算机科学与技术学院指导老师姓名毛雪涛学生姓名学生专业班级软件sy1…
20xx年秋季学期计算机网络编程实验报告班级计121班学号12101020xx8姓名刘杰总成绩评语指导教师签字日期实验一登陆页面及…
计算机科学与工程学院网络工程专业20XX级网络编程实验大作业报告网络编程实验大作业报告即时通讯软件的设计与实现完成日期20xx41…
实验一TCPSocketAPI程序设计一预备知识1网络编程基本概念网络上的计算机间的通讯实质上是网络中不同主机上的程序之间的通讯在…
嵌入式实验报告题目linux串口和网络编程一实验目的1强化本学期所学的相关的内容2掌握串口相关设置3强化基于TCP网络传输的三次握…
实验3计算机网络实验网络编程1一实验目的1熟悉和掌握网络编程的基本方法和步骤2进一步理解clientserver交互模式3加深学生…
河南师范大学设计性实验报告Linux网络编程实验河南师范大学综合性设计性实验项目简介注开课时间填本实验项目所有实验班的具体上课时间…
实验3计算机网络实验网络编程1一实验目的1熟悉和掌握网络编程的基本方法和步骤2进一步理解clientserver交互模式3加深学生…
网络编程实验报告基于TCP的网络文件传输实验报告一实验目的1熟悉TCPIP协议的功能和网络操作2编写小型的socket应用程序初步…
华北科技学院计算机系综合性实验实验报告课程名称网络编程实验学期20xx至20xx学年第1学期学生所在系部计算机系年级09级专业班级…