TCP文件传输程序的设计书.docx

上传人:b****5 文档编号:6347406 上传时间:2023-01-05 格式:DOCX 页数:18 大小:92.42KB
下载 相关 举报
TCP文件传输程序的设计书.docx_第1页
第1页 / 共18页
TCP文件传输程序的设计书.docx_第2页
第2页 / 共18页
TCP文件传输程序的设计书.docx_第3页
第3页 / 共18页
TCP文件传输程序的设计书.docx_第4页
第4页 / 共18页
TCP文件传输程序的设计书.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

TCP文件传输程序的设计书.docx

《TCP文件传输程序的设计书.docx》由会员分享,可在线阅读,更多相关《TCP文件传输程序的设计书.docx(18页珍藏版)》请在冰豆网上搜索。

TCP文件传输程序的设计书.docx

TCP文件传输程序的设计书

TCP文件传输程序设计书

一、实验名称:

TCP文件传输程序

二、实验要求

1、设计一个应用程序,该应用程序能够实现网络中两台计算机之间传输文件。

2、一个程序既能够建立服务器又能够以终端的形式连接服务器。

3、终端或者服务器既能够发送文件又能够接收文件。

4、传送文件类型应为任何类型,文件大小为任意。

三、总体规划

1、网络传输协议的选择

在TCP/IP协议栈中,有两个高级协议是我们网络应用程序编写者应该了解的,它们"传输控制协议"(TransmissionControlProtocol,简称TCP和"用户数据报协议"(UserDatagrmProtocol,简称UDP。

TCP是面向连接的通信协议,TCP提供两台计算机之间的可靠无错的数据传输。

应用程序利用TCP进行通信时,源和目标之间会建立一个虚拟连接。

这个连接一但建立,两台计算机之间就可以把数据当作一个双向字节流进行交换。

UD是无连接通信协议,UD不保证可靠数据的传输,但能够向若干个目标发送数据,接收发自若干个源的数据。

简单地说,如果一个主机向另外一台主机发送数据,这一数据就会立即发出,而不管另外一台主机是否已准备接收数据。

如果另外一台主机收到了数据,它不会确认收到与否。

为了使两台计算机之间传输的文件数据不会丢失或发生错误,应该采用TC助、议。

2、TCP协议在VC+中的实现

在VC++中,网络协议的实现有以下几种方式:

a、采用WinSocketAPI函数。

API函数中提供了基本Socket的系统调用,具体实现方法为服务器端首先要调用socket()函数建立一个流式套接字,用bind()函数与本机的一个端口建立关联,继续调用listen()函数将套接字置于被动的侦听方式以监听连接,然后调用accept()函数进入等待状态之后才可以接收来自客户端的请求,一旦接收到客户端通过connect发出的连接请求,accept将返回一个新的套接字描述符。

通过此套接字描述符调用send()或recv()函数即可与客户端进行数据收发。

待数据传送完成,服务器客户端调用closesocket()关闭套接字。

该方法在编程过程中需要注意socket连接的整个过程,编程工作量大,编程效率低,单却可以加深对网络协议的认识。

程序流程示意图如下:

b、采用VC+中提供的MF类,CAsyncSocket或CSocket.

两个类都对WinSocketAPI进行了圭寸装,CSocket对它的圭寸装比CAsyncSocket更深,使得对于从未接触过WinSocketsAPI的编程程序员,也能够编写网络程序。

而本程序也是米用了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_WEn(如果标记为0,说明未传输完毕,以后还有数据传送过来,如果标记为1,说明已经传输完毕,可以进行

一些后续工作。

而另一端,每接受一个数据包,就检查以下该标记位,以确定是否传输完毕。

四、实验运行测试

1、建立服务器

连玄煨吳■豈|

弟IE碗韵J

用于建立服务器

期方航务噩地址.

2、客户端建立连接

3、发送文件

a、客户端发送

b、服务器端接收

 

■ff

S33-sis、丈和玄雷kJ曰

!

刃^^H3r

蛊监-馬U刪

冃罢禱E■軸tgltsl‘旦•nnw•专e-4nwffi^^,of

弗嫌雪it隔皱帝嫌霆

<购半®爛皿

秤聽聲」一总鲁^一.^8k§一赞

-即沟世汽

--期贺斟bu,目•00血・ZOE-

戶阳誓工曲

®嬪

蛋春^

 

5、在E:

盘中查找接收到的文件

*Jisr_i(r

丈1牛|£|询轮|印■&若世)聪喩电:

IRQJ

X勺[巨?

*

I

尢■卜I类出I他

曲日期

五、心得体会

在这五天的时间里我按照设计书的要求应用网络编程的相关知识编写了一个实现文件传输的应用程序。

在编写过程中,收获颇丰。

首先是对TCP*、议和UD协议有了更进一步的认识;其次在编写过程中,通过翻阅书籍学习了VC+编程和MFC勺相关容,拓展了自己的知识面,学到了很多在课堂上无法学到的东西。

当然,由于对Socket编程毕竟还不太熟练,难免会出现一些问题,现将这些问题总结如下:

1开始时在数据串行化的设计时,直接用

CArchive类的对象<

或CArchive类的对象>>CFile类的对象

出现错误,查阅MSD发现不能直接用<<运算符不能直接对CFile类的对象进行操作。

2、接收端操作同数据的传输必须同步,即必须确保在接收数据时,应确保数据已经传送到了接收端,也就是防止因为数据为传送过来而导致的接收失败。

为了防止接收

失败而导致数据丢失,应反复接收,直到接收数目符合为止。

女如:

i=0;

while(i

i=ar.Read(&Bbuf[i],m_WNum-i)+i;

所幸的是这些问题都在参考资料和老师的帮助下得到了解决。

最终圆满的完成了

课程设计任务书的要求。

自身分析问题和解决问题的能力也得到了提升,为以后的实

验设计奠定了良好的基础。

在这里要感老师对我的悉心指导,您辛苦了!

六、程序源代码

1、建立服务器侦听套接字的类CListenSocket的定义与实现定义部分:

classCListenSocket:

publicCsocket//该类用于服务器端的侦听

{

public:

CTcpDlg*m_pSendDlg;//加该成员为了调用其的函数。

public:

CListenSocket(CTcpDlg*pSendDlg);

virtual~CListenSocket();

public:

virtualvoidOnAccept(intnErrorCode);

};实现部分:

CListenSocket:

:

CListenSocket(CTcpDlg*pSendDlg)

{

m_pSendDlg=pSendDlg;

}

voidCListenSocket:

:

OnAccept(intnErrorCode)//当服务器端收到客

//户端的连接请求时执行的代码。

{

CSocket:

:

OnAccept(nErrorCode);m_pSendDlg->ProcessAccept();

}

2、建立数据传输套接字的类CTransSocket的定义与实现定义部分:

classCTransSocket:

publicCsocket//该类用于两端的连接和传输

{

public:

CTcpDlg*m_pSendDlg;

public:

CTransSocket(CTcpDlg*pSendDlg);

virtual~CTransSocket();

public:

virtualvoidOnReceive(intnErrorCode);

};实现部分:

CTransSocket:

:

CTransSocket(CTcpDlg*pSendDlg){m_pSendDlg=pSendDlg;

}

voidCTransSocket:

:

OnReceive(intnErrorCode)//当收到发送

//端发送的数据时执行的代码。

{CSocket:

:

OnReceive(nErrorCode);m_pSendDlg->SetTip(CString("有数据传送到"));m_pSendDlg->SendOrRecv=2;

m_pSendDlg->JudgeButton();

}

3、用于数据串行化的类CSave勺定义与实现:

定义部分:

classCSave:

publicCObject

{

public:

WORDm_WEnd;//标记数据传输是否结束,结束-0未结束-1意外-2WORDm_WNum;//标记Bbuf[]中元素的个数

BYTEBbuf[1024];

public:

CSave();virtual~CSave();voidInit();virtualvoidSerialize(CArchive&ar);

};实现部分:

Init();

}

voidCSave:

:

Init()

{//inti;//m_WEnd=1;

CSave:

:

CSave(){

//重新定义一个Init()的原因是不仅在CSave类初始化时将类各变量值初始状态,还可以在以后也可以。

//结束标志

for(i=0;i<1024;i++)Bbuf[i]=0;

}

voidCSave:

:

Serialize(CArchive&ar)//数据串行化

{

unsignedinti=0;if(ar.IsStoring())

{

ar<

//数组中的值发送出

for(i=0;i

}else

{

i=0;

ar>>m_WEnd;

ar>>m_WNum;

while(i

i=ar.Read(&Bbuf[i],m_WNum-i)+i;

4、主对话框CTcpDIg类的定义与实现:

定义部分:

cIassCTcpDIg:

pubIicCDiaIog{

系统定义部分省略...

pubIic:

CListenSocket*m_pListenSocket;

CTransSocket*m_pTransSocket;

CSocketFile*m_pFile;CFile*m_pBasicFile;CArchive*m_pArchiveIn;CArchive*m_pArchiveOut;CStringm_strFileName;

//用于和CSocket连接

//CSocket的两个缓冲区

//用于存储文件名

//send1;receive2;nothing0;//Server-1,Client-2//用于控制意外中断发送信号

intSendOrRecv;

intServerClient;

intiEnd;

intm_nPort;voidProcessAccept();voidProcessRecv();

voidInitConnection();

BOOLConnectSocket(CStringstrIP);

voidSendFile(CStringstrFileName,WORDWEnd=1);intReceiveFile(CFile*m_pBasicFile,CStringstrFileName,DWORD*wNum);voidJudgeButton();

voidSetTip(CStringstr);

public:

CTcpDlg(CWnd*pParent=NULL);//standardconstructor

virtual~CTcpDlg();

系统控件变量定义省略...系统定义函数省略...

protected:

afx_msgvoidOnBUTTONListen();afx_msgvoidOnBUTTONStop();

afx_msgvoidOnBUTTONConnect();afx_msgvoidOnBUTTONCut();

afx_msgvoidOnBUTTONBrowser();afx_msgvoidOnBUTTONSend();afx_msgvoidOnBUTTONSave();afx_msgvoidOnBUTTONRecv();

};实现部分:

系统定义函数实现省略...

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;

deletem_pTransSocket;

m_pTransSocket=NULL;

deletem_pListenSocket;m_pListenSocket=NULL;

deletem_pBasicFile;

m_pBasicFile=NULL;

deletem_pArchiveIn;

deletem_pArchiveOut;

m_pArchiveIn=NULL;

m_pArchiveOut=NULL;

deletem_pFile;

m_pFile=NULL;

}

BOOLCTcpDlg:

:

OnInitDialog()

{

系统添加部分省略...

CDialog:

:

OnInitDialog();

m_nPort=1234;

m_AddCtrl.SetAddress(192,168,0,1);

JudgeButton();

SetTip(CString("初始状态"));

returnTRUE;

}

voidCTcpDlg:

:

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)

}

elseif(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);

}

elseif(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;

}

elseif(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;

}

voidCTcpDlg:

:

SetTip(CStringstr)//调整状态区的文字显示{

m_EditTip.SetWindowText(str);

}

voidCTcpDlg:

:

ProcessAccept()//应答客户端的连接请求

{m_pTransSocket=newCTransSocket(this);if(m_pListenSocket->Accept(*m_pTransSocket)){

InitConnection();m_pListenSocket->Close();deletem_pListenSocket;m_pListenSocket=NULL;

JudgeButton();

SetTip(CString("有客户端连接"));

}

else

{

deletem_pListenSocket;m_pListenSocket=NULL;deletem_pTransSocket;m_pTransSocket=NULL;

JudgeButton();SetTip(CString("连接失败"));

}}

voidCTcpDlg:

:

InitConnection()//初始化CSocket缓冲区及与CSocketFile{//的连接。

m_pFile=newCSocketFile(m_pTransSocket);

m_pArchiveIn=newCArchive(m_pFile,CArchive:

:

load,256*1024);m_pArchiveOut=newCArchive(m_pFile,CArchive:

:

store,256*1024);

}

voidCTcpDlg:

:

OnBUTTONListen()

{

//TODO:

Addyourcontrolnotificationhandlercodeherem_pListenSocket=newCListenSocket(this);if(m_pListenSocket->Create(m_nPort))

{

if(m_pListenSocket->Listen())

{

JudgeButton();

SetTip(CString("服务器已启动"));

ServerClient=1;

iEnd=1;

return;

}

}

deletem_pListenSocket;m_pListenSocket=NULL;JudgeButton();

SetTip(CString("服务器无法启动"));ServerClient=0;

}

voidCTcpDlg:

:

OnBUTTONStop()

{

iEnd=2;deletem_pListenSocket;m_pListenSocket=NULL;deletem_pTransSocket;m_pTransSocket

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 工学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1