Linux环境下如恰当的使用TCP协议编写网络传输程序.docVIP

Linux环境下如恰当的使用TCP协议编写网络传输程序.doc

  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文档。上传文档
查看更多
Linux环境下如恰当的使用TCP协议编写网络传输程序

Linux环境下如何恰当的使用TCP协议编写网络传输程序【转】 Linux环境下如何恰当的使用TCP协议编写网络传输程序 2010-05-11 08:55 转载自 xiangpengmeng 最终编辑 xiangpengmeng 声明本文属于转载! 学习中!!! 摘 要:本文介绍了Linux环境下TCP协议编写网络传输程序的几点考虑。作者提出了在使用此协议时,构造消息边界、区分程序控制数据与实际数据的设计思 路。作者将客户与服务器之间的交互信息抽象成不同的命令,实现了一个文件传输协议和基于命令式交互的网络服务器、客户的架构模型。 关键词:Linux,TCP,socket 一、背景 在2008年夏季小学期里,作者学习了Linux的下的并发网络服务器的设计理论,根据老师的要求,编制了并发文件传输的服务器、客户端程序。 在编写网络程序的过程中,作者考虑到了TCP协议的原理和一般网络环境的特点,提出了平时大家不太注意的几个问题,并给出了解决方案,实现了自己的文件传输协议。 二、使用TCP协议编写文件传输程序的三个问题 1、无法区分消息边界 平时在谈论TCP时,我们都能够注意到它与UDP的一点区别,那就是TCP的传输是流式的,而UDP的传输是面向数据报的,但是一般的同学在第一次 编写传输程序时,却没有意识到这一点。实际上,TCP的流式传输,体现在编程上,就是TCP不为应用程序保留消息边界。也就是说在一端调用send(), 发送一定的字节数,譬如2K个字节,在另一端调用recv()时,也许只收到其中的前1K个字节,需要再调用一次recv()才能把所有的字节收完整。这 是因为在接收端的TCP程序收到合适数量的字节数之后或者缓存满之后,就会把缓冲区中的数据提交给应用程序,这时recv()函数返回,但实际上还有一些 字节在网络上传送。若发送端调用两次send()分别发送了0.5K和2K个字节,接收端第一次接收可能会接收到1K个字节,第二次会接受到剩下的 1.5K个字节。如果发送的0.5K和2K个字节分别代表服务器发送给客户的两个文件,接收方就无法区分两次收到的数据分别是哪个文件中的内容了。 这种特点在客户与服务器需要进行一定数量的交互应答时显得非常不方便,传送的消息全部杂糅在一起,区分不出边界,需要程序员自己处理边界的问题。 2、不恰当的使用发送函数 另外一个问题是一些同学使用循环,按一个字节一个字节的发送文件的内容,这样做是非常有害的。虽然程序把数据推送到缓冲区后,TCP会尽量把数据集 合成MSS长度发送出去,但是若数据到达的速率比较慢,即使不到一个MSS的长度,TCP等待超过一段时间后,也会导致一次发送。另外,在关闭了 Nagle算法后,这种一次要求TCP发送一个字节的函数调用的效率会更低,如果文件比较大,速度会慢得不能忍受。消费IP和TCP的较长头部,却只带走 很少数量字节的净荷,对带宽的利用率就变低了。 3、控制信息与数据无法区分 最后一个问题是,在文件较大的时候,无法一次全部读入内存,也无法一次就发送完毕,需要边读边发,这样就导致了多次send()函数的调用,客户与服务器进行请求应答会话时,传输的控制信息也要使用send(),由于没有消息边界,这些内容在recv()时就无法区分。 在本次任务中,程序的要求比较简单,因此几乎没有控制信息,在更复杂的场合,这个问题是不可回避的。 4、为什么平时都没有发现问题 这些问题大家平时都不容易考虑到,是因为每次编写网络程序都比较简单,实验时也只发送小文件,看不到错误的发生。为了引发这些错误,我编写了一个程 序,其逻辑很简单,先把文件全部读到一个一维字节数组中,再一次调用send()函数全部发出去,在接收方调用一次recv()函数收取数据,再将数据写 到文件中。这个程序在发送小文件时工作得很好,在发送一个2.1K的文件时,接收方只调用一次recv(),仅收到了1.4K,剩下的数据还留在接收方缓 冲区中。 三、文件传输程序的设计思路 1、区分消息边界 在链路层的协议中,区分消息边界用的是位填充与字符填充法。在本程序中,使用另外一种办法。不使用填充法是因为无论是字符填充还是位填充,都要扫描 一遍所有的数据,寻找出与边界相冲突的模式。这在链路层是比较合理的,因为要计算桢检验信息,必然要做全部的扫描,这时就可以顺便找出冲突并进行填充。但 是在应用层的程序中,如果每次都要把所有的数据都扫描一遍,会减慢处理数据的速度。 作者的办法是先发4字节定长的数据表示将来要发送的消息的长度,再一次把整个消息都推送给send()函数,放到缓冲区中,让TCP协议自己决定何 时从缓冲区中取出数据、取多少数据发送到网络上。接收方每次先接收4字节的数据,确定将来接收数据的长度,根据这个信息,再不停的调用recv()函数, 并累积已经收

文档评论(0)

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

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

1亿VIP精品文档

相关文档