ImageVerifierCode 换一换
格式:DOCX , 页数:37 ,大小:4.74MB ,
资源ID:21101694      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/21101694.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(基于TCP的文件传输程序Word文件下载.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

基于TCP的文件传输程序Word文件下载.docx

1、传输前的接收提醒以及传输过程中的控制。 2、软件模块划分 本程序可以划分成以上三个模块:传输控制模块,文件传输模块和服务连接模块。其中:服务连接模块用来建立客户端到服务器的连接 文件传输模块主要用两个线程:_SendThread和_ListenThread来完成,实现发送和接收文件的功能。 传输控制模块主要通过封装好的可串行化信息类CMessage互相传递两端的文件操作消息,响应“暂停传输”,“关闭连接”等功能五、设计步骤 1、服务连接模块 先要建立起客户端与服务器之间的连接,大致过程如下:1 服务器启动: if(m_nServerType = SERVER) /创建服务器套接字 m_psoc

2、kServer = new CListenSocket(this); if(!m_psockServer-Create(m_wPort) /绑定端口 delete m_psockServer; m_psockServer = NULL; MessageBox(GetError(GetLastError(), _T(错误), MB_ICONHAND); return ; /开启线程,监听客户端连接Listen() 2 客户端填入相应的IP地址,连接服务器 if(CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS)-IsBlank() MessageBox(IP 地址

3、不能为空, , MB_ICONHAND); /创建客户端套接字 m_psockClient = new CClientSocket(this);m_psockClient-Create() delete m_psockClient; m_psockClient = NULL; /与服务器建立连接 CString strIPAddress; GetDlgItem(IDC_IPADDRESS)-GetWindowText(strIPAddress);Connect(strIPAddress, m_wPort) /Connect连接服务器,服务器用OnAccept响应 /初始化客户端套接字 m_ps

4、ockClient-Init();3 服务器响应 CClientSocket* pSocket=new CClientSocket(this); /接收请求后获得新的套接字,交由新的套接字处理请求 if(m_psockServer-Accept(*pSocket) /非零则接收连接请求成功 /初始化Accpet返回的套接字 pSocket- CMessage* pMsg; /检测套接字是否为空,空则还没有连接任何客户端 if(m_psockClient=NULL) pMsg=new CMessage(CONNECT_BE_ACCEPT); pSocket-SendMsg(pMsg); /发回“

5、这边可以连接”消息回去,客户端的Receive接收 m_psockClient=pSocket; /若为服务器,则之前未初始化,可保存这个套接字,用来跟客户端交互 GetDlgItem(IDC_SELECT_FILE)-EnableWindow(TRUE); else pMsg=new CMessage(CONNECT_BE_REFUSE);4 客户端收到连接成功消息 if(pMsg-m_nType=CONNECT_BE_ACCEPT) GetDlgItem(IDC_SELECT_FILE)- return;2、传输控制模块 该工程用了两对套接字,一对用来接收传输控制消息,一对用来收发文件。我

6、们这个模块用的是第一对 在MFC中定义了一个在套接字编程中使用的CSocketFile类,可以充分发挥CSocket类的特性。CSocketFile类是CFile的派生类,主要用来在Windows Sockets编程中发送和接收序列化数据(如结构体数据)。通过把CSocketFile类对象、CArchive对象和CSocket创建的套接字对象联系起来,可以实现数据的加载(接收)和存储(发送)。 MFC集成CSocketFile、CSocket、CArchive可以简化网络传输。下图可以直观地反应这三者是如何结合来在客户端和服务器之间传输消息的 先来看看服务器和客户端的套接字初始化工作: m_p

7、File = new CSocketFile(this); m_pArchiveIn = new CArchive(m_pFile,CArchive:load); m_pArchiveOut = new CArchive(m_pFile,CArchive:store); 这样一来,当使用m_pArchiveIn对象来调用可串行化消息类CMessage的Serialize时,接收方就能响应OnReceive消息,来完成控制信息的传递。 本工程在主类CsendFileDlg中定义了传输的三种状态: m_bIsWait: 已连接,正在等待传输文件 m_bIsTransmitting: 正在传输文件

8、m_bIsStop: 传输已终止本工程定义的可串行化消息类CMessage,用来传递文件名m_strFileName、文件长度m_dwFileSize以及当前的传输状态m_nType,大致流程如下图:其中,我在建工程的时候,把客户端和服务器集成在了一个界面OnReceive就用来接收两方的消息,关键代码如下: CMessage* pMsg=new CMessage(); pSocket-ReceiveMsg(pMsg);m_nType=CONNECT_BE_REFUSE) MessageBox(_T(服务器正在和另外的客户端连接,稍等),_T( delete m_psockClient; m_

9、psockClient=NULL; return ; if (pMsg-m_nType=DISCONNECT)对方已经关闭), _T(警告 if(m_psockClient != NULL) /接收请求m_nType=REQUEST) m_bIsWait=TRUE; /忙状态置1 m_strFileName=pMsg-m_strFileName; m_dwFileSize=pMsg-m_dwFileSize; CString strName,strSize; strName.Format(文件名:%s,m_strFileName); strSize.Format(文件大小:%ld字节,strS

10、ize); /这里完成了发送文件前给对方提示的功能 if(MessageBox(strName+rn+strSize,对方请求向你发送文件,MB_OKCANCEL)=IDCANCEL) CMessage* pMsg = new CMessage(REFUSE); m_psockClient- return; CFileDialog dlg(FALSE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,所有文件(*.*)|*.*|,this); dlg.m_ofn.lpstrTitle=_T(另存为); strcpy(dlg.m_ofn.lpstrFi

11、le,m_strFileName.GetBuffer(m_strFileName.GetLength(); if(dlg.DoModal()=IDOK) if(m_bIsWait=FALSE) MessageBox(_T(对方已经取消文件发送), MB_ICONEXCLAMATION); return ; m_bIsClient=FALSE; m_strPath=dlg.GetPathName(); /启动接收文件的线程 GetDlgItem(IDC_SR)-SetWindowText(已接收: pThreadListen = :AfxBeginThread(_ListenThread, th

12、is); /服务器接收到RUEST,开启接收文件线程 if(m_bIsWait = TRUE) /告诉对方文件发送请求被拒绝 CMessage* pMsg = new CMessage(REFUSE); m_bIsWait = FALSE; /当对方同意,并且已经准备好接收文件的时候m_nType=ACCEPT) KillTimer(1); m_bIsWait=FALSE; /等待状态清空 /启动发送文件线程 GetDlgItem(IDC_SR)-已发送: pThreadSend=:AfxBeginThread(_SendThread,this); /当发送文件请求被拒绝m_nType=REF

13、USE)请求被拒绝 /当对方取消文件传输时执行该if语句里面的内容m_nType = CANCEL) 3、文件传输模块 两个线程: _ListenThread():建立新的监听套接字,准备接收文件 _SendThread(): 建立客户端套接字,连接监听套接字,发送文件 当两方建立了可靠的连接,一方选择文件后,就会使用传输控制模块给对方发送文件发送请求,对方的ProcessReceive接收到后查看当前的消息状态,(上个模块的OnReceive已经写得很清楚),同意接受后,开启文件接收线程,同时给发送方返回一个准备完成状态,于是,发送方开启文件发送线程,最后完成文件的传输工作,同时置状态m_b

14、IsStop为TRUE,便于双方传输控制1 发送线程关键函数SendFilevoid CSendFileDlg:SendFile(CSocket& senSo) m_bIsTransmitting=TRUE; CFile file; if (!file.Open(m_strPath,CFile:modeRead|CFile:typeBinary) AfxMessageBox(_T(文件打开失败); senSo.Close(); m_ctrlProgress.SetRange32(0,m_dwFileSize); int nSize=0,nLen=0; DWORD dwCount = 0; ch

15、ar bufBLOCKSIZE=0; file.Seek(0,CFile:begin); /开始传送 while(1) /每次读取BLOCKSIZE大小 nLen=file.Read(buf,BLOCKSIZE); if(nLen=0) break; /发送文件内容 nSize=senSo.Send(buf,nLen); dwCount+=nSize; m_ctrlProgress.SetPos(dwCount); CString strTransfersSize; strTransfersSize.Format(%ld 字节,dwCount); /设置进度条属性 GetDlgItem(IDC

16、_RECEIVE_SIZE)-SetWindowText(strTransfersSize); int p=(double)dwCount)/(int)m_dwFileSize+1)*100+1;%d,p); strTransfersSize+=%; /判断用户是否停止发送 if(m_bIsStop) m_bIsStop=FALSE; if (nSize=SOCKET_ERROR) file.Close(); senSo.Close(); if(m_dwFileSize=dwCount)文件发送成功 else文件发送失败 m_ctrlProgress.SetPos(0); m_bIsTrans

17、mitting = FALSE;2 接收线程关键函数ReceiveFileReceiveFile(CSocket& recSo) /停止等待超时计时器 KillTimer(2); m_bIsWait=FALSE; /正在传输置1 int nSize=0; DWORD dwCount=0; CFile file(m_strPath,CFile:modeCreate|CFile:modeWrite); /开始接收文件 while (1) /每次接收BLOCKSIZE大小的内容 nSize=recSo.Receive(buf,BLOCKSIZE); if(nSize=0) /写入文件 file.Wr

18、ite(buf,nSize); GetDlgItem(IDC_RECEIVE_SIZE)- GetDlgItem(IDC_PECENT)-SetWindowText(strTransfersSize) /用户是否停止了接收 recSo.Close();文件接收成功文件接收失败六、关键问题及其解决方法 1、在传输文件前、中、后能让程序响应各类控制消息集成后的互通消息代码很简单:void Serialize(CArchive& ar) if(ar.IsStoring() ar CSocket、CSocketFile、CArchive三个类的联动,完美地解决了这个问题,在传输文件的过程中,若一方有事

19、件发生(暂停传输、关闭连接等等),则改变预先设定的状态值,SendMsg给CSocketFile,触发对方的虚函数OnReceive,从而解决通信问题。 2、解决单线程传输阻塞的非“非阻塞”式方法在使用AfxBeginThread实现多线程的同时,也增加了诸如发送超时、接收超时等判断(使用Windows定时器SetTimer响应OnTime来实现),这一定程度上增强了程序的鲁棒性 文件的传输时阻塞式的,所以在主线程中直接传输文件必然导致界面卡死,所以这里我用到了多线程技术,为传输文件和接受文件分别开设线程。1 _ListenThreadUINT _ListenThread(LPVOID lpa

20、ram) CSendFileDlg* pDlg=(CSendFileDlg*)lparam; /创建服务器端套接字 CSocket sockSrvr; if(!sockSrvr.Create(pDlg-m_wPort+PORT) pDlg-TransfersFailed(); :MessageBox(HWND)lparam, pDlg-GetError(GetLastError(), _T(), MB_ICONHAND|MB_OK); return -1;sockSrvr.Listen() /监听 /接收套接字已经创建向主对话框发送自定义消息,该消息发送一个消息给发送方,可以开始传数据 pDlg-SendMessage(WM_ACCEPT_TRANSFERS); CSocket recSo;

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

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