文件传输程序设计讲解
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Internet网络程序设计实验报告基于Socket的文件传输程序设计
姓名:莫敌
班级:软件 0904
学号:U200917895
指导老师:陆永忠
2012.03.31
目录
1 实验目的及要求 (3)
1.1 实验目的 (3)
1.2 实验要求 (3)
2 实验环境 (3)
3 实验程序设计 (3)
3.1 设计思想 (3)
3.2 程序设计流程框图 (4)
3.3 详细设计 (5)
3.3.1 界面设计 (5)
3.3.2 主要功能实现 (6)
3.4 运行结果 (9)
4 实验感想 (11)
1实验目的及要求
1.1实验目的
熟悉Socket的通讯机制,了解网络程序的设计方法。重点掌握基于TCP协议的Socket 网络编程。
1.2实验要求
设计界面,在服务器端和客户端传输图片和文件。如果是图片请显示该图片,如果是其他文件,则保存。
2实验环境
编译环境:Windows 7 + Visual Studio 2010 使用MFC编写。
运行环境:Windows 7操作系统。
3实验程序设计
3.1设计思想
根据实验的要求:在服务器和客户端之间传输文件和图片,则需要程序提供一种可靠的网络传输服务来保证文件在传输过程中无丢失、损坏。在分析了传输层协议TCP协议和UDP 协议后,了解到TCP协议提供的是一种面向连接的、可靠的字节流服务,而UDP协议提供的是一种无连接的、不可靠的数据报服务。由于程序的需求,即必须保证文件传输的可靠性,于是,我采用基于TCP协议的Windows sockets来设计实现本实验。
3.2程序设计流程框图
图1程序设计流程框图
3.3详细设计
基于TCP的socket编程流程:
服务器端:
创建套接字(socket)。
将套接字绑定到一个本地地址和端口上(bind)。
将套接字设为监听模式,准备接收客户端请求(listen)。
等待客户端请求到来。当请求到来后,接收连接请求,返回一个新的对应于此次连接的套件字(accept)。
用返回的套接字和客户端进行通信(send/recv)。
返回,等待另一客户端请求。
关闭套接字。
客户端:
创建套接字(socket)。
向服务器发出连接请求(connect)。
和服务器端进行通信(send/recv)。
关闭套接字。
3.3.1界面设计
图2程序界面
由于程序实现的功能单一简单,所以我的程序界面设计如图2所示。
程序由两个用户可操作的控件组成:IP地址控件,用户输入将要接收文件的接收方IP 地址;“发送文件”按钮,单击选择用户要发送的文件并发送所选文件数据。
3.3.2主要功能实现
套接字库加载:
AfxSocketInit()
接收线程:
UINT RecvProc( LPVOID pParam )
{
while (TRUE)
{
CSocket tmpSock;
CSocket servSock;
tmpSock.Create(5000);
tmpSock.Listen(1);
tmpSock.Accept(servSock);
char fileNameRecv[500] = {0};
int a = servSock.Receive(fileNameRecv, 500);
CFileDialog saveDlg(FALSE, NULL, NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, "所有文件(*.*)|*.*||");
saveDlg.m_ofn.lpstrFile = fileNameRecv;
if (IDOK == saveDlg.DoModal())
{
CFile recvFile;
CString recvPathName;
recvPathName = saveDlg.GetPathName();
recvFile.Open(recvPathName, CFile::modeCreate | CFile::modeWrite);
UINT uiLength;
servSock.Receive(&uiLength, 4);
int iBufSize = 1024 * 5;
int iSize = iBufSize;
LPBYTE pBuf = new BYTE[iBufSize];
int iNumByte;
UINT uiTotal = 0;
while (uiTotal < uiLength)
{
if ((int)(uiLength - uiTotal) < iBufSize)
{
iSize = uiLength - uiTotal;
}
int iCount = 0;
while (iCount < iSize)
{
iNumByte = servSock.Receive(pBuf, iSize - iCount);
iCount += iNumByte;
recvFile.Write(pBuf, iNumByte);
}
uiTotal += iCount;
}
recvFile.Close();
servSock.Close();
char ext[10];
CString tmpExt;
_splitpath(recvPathName, NULL, NULL, NULL, ext);
tmpExt = ext;
if(".bmp"== tmpExt || ".pcx"== tmpExt || ".tiff"== tmpExt || ".gif"== tmpExt || ".jpg" == tmpExt || ".jpeg" == tmpExt || ".tga" == tmpExt || ".exif" == tmpExt || ".fpx" == tmpExt)
{
ShellExecute(NULL, "open", recvPathName, NULL, NULL, SW_SHOWNORMAL);
}
}
}
return 0;
}
发送文件按钮:
void CmyFileTransferDlg::OnBnClickedBtnSend()
{
CFileDialog openDlg(TRUE, NULL, NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, "所有文件(*.*)|*.*||");
if (IDOK == openDlg.DoModal())
{
CString openFileName;
openFileName = openDlg.GetFileName();
CSocket sendSock;
sendSock.Create();
CString IPstr;
this->GetDlgItem(IDC_IPADDRESS1)->GetWindowText(IPstr);
if (sendSock.Connect(IPstr, 5000) == 0)
{
return;
}
CFile sendFile;