UDP实现靠文件传.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
UDP实现可靠文件传输 ??????? 大家都清楚,如果用TCP传输文件的话,是很简单的,根本都不用操心会丢包,除非是网络坏了,就得重来。用UDP的话,因为UDP是不可靠的,所以用它传输文件,要保证不丢包,就得我们自己写额外的代码来保障了。本文就说说如何保证可靠传输。 ??????? 要实现无差错的传输数据,我们可以采用重发请求(ARQ)协议,它又可分为连续ARQ协议、选择重发ARQ协议、滑动窗口协议。本文重点介绍滑动窗口协议,其它的两种有兴趣的可参考相关的网络通信之类的书。 ??? ??????? 采用滑动窗口协议,限制已发送出去但未被确认的数据帧的数目。循环重复使用已收到的那些数据帧的序号。具体实现是在发送端和接收端分别设定发送窗口和接收窗口。 ???????? (1)发送窗口 ??????? 发送窗口用来对发送端进行流量控制。发送窗口的大小Wt代表在还没有收到对方确认的条件下,发送端最多可以发送的数据帧的个数。具体意思请参考下图: ???????????????????????????????????????????????????????? ??????? (2)接收窗口 ??????? 接收窗口用来控制接收数据帧。只有当接收到的数据帧的发送序号落在接收窗口内,才允许将该数据帧收下,否则一律丢弃。接收窗口的大小用Wr来表示,在连续ARQ协议中,Wr = 1。接收窗口的意义可参考下图: ?????????????????????????????????????????????????????? ??????? 在接收窗口和发送窗口间存在着这样的关系:接收窗口发生旋转后,发送窗口才可能向前旋转,接收窗口保持不动时,发送窗口是不会旋转的。这种收发窗口按如此规律顺时钟方向不断旋转的协议就犯法为滑动窗口协议。 ??????? 好了,在上面对滑动窗口协议有大致了解后,我们还是进入正题吧:) ??????? 发送端的发送线程: ??????? int? ret; ?int? nPacketCount = 0; ?DWORD dwRet; ?SendBuf sendbuf; ?DWORD dwRead; ?DWORD dwReadSize; ?SendBuf* pushbuf; ?//计算一共要读的文件次数,若文件已读完,但客户端没有接收完, ?//则要发送的内容不再从文件里读取,而从m_bufqueue里提取 ?nPacketCount = m_dwFileSize / sizeof(sendbuf.buf); ? ?//若不能整除,则应加1 ?if(m_dwFileSize % sizeof(sendbuf.buf) != 0) ? ++nPacketCount; ?SetEvent(m_hEvent); ?CHtime htime; ?//若已发送大小小于文件大小并且发送窗口前沿等于后沿,则继续发送 ?//否则退出循环 ?if(m_dwSend m_dwFileSize)? // 文件没有传输完时才继续传输 ?{ ? while(1) ? { ?? dwRet = WaitForSingleObject(m_hEvent, 1000); ?? if(dwRet == WAIT_FAILED) ?? { ??? return false; ?? } ?? else if(dwRet == WAIT_TIMEOUT) ?? { ??? //重发 ??? ::EnterCriticalSection(m_csQueue);? // 进入m_bufqueue的排斥区 ??? ret = m_hsocket.hsendto((char*)m_bufqueue.front(), sizeof(sendbuf)); ??? ::LeaveCriticalSection(m_csQueue);? // 退出m_bufqueue的排斥区 ??? if(ret == SOCKET_ERROR) ??? { ???? cout 重发失败,继续重发 endl; ???? continue; ??? } ??? ResetEvent(m_hEvent); ??? continue; ?? } ?? //若发送窗口大小 预定大小 已读文件次数(nReadIndex) 需要读文件的次数(nReadCount),则继续读取发送 ?? //否则,要发送的内容从m_bufqueue里提取 ?? if(m_dwSend m_dwFileSize) ?? { ??? dwReadSize = m_dwFileSize - m_dwSend; ??? dwReadSize = dwReadSize MAXBUF_SIZE ? dwReadSize

文档评论(0)

mv2323 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档