linux环境下如何恰当的使用tcp协议编写网络传输程序

linux环境下如何恰当的使用tcp协议编写网络传输程序

ID:36972465

大小:160.50 KB

页数:9页

时间:2019-05-06

linux环境下如何恰当的使用tcp协议编写网络传输程序_第1页
linux环境下如何恰当的使用tcp协议编写网络传输程序_第2页
linux环境下如何恰当的使用tcp协议编写网络传输程序_第3页
linux环境下如何恰当的使用tcp协议编写网络传输程序_第4页
linux环境下如何恰当的使用tcp协议编写网络传输程序_第5页
资源描述:

《linux环境下如何恰当的使用tcp协议编写网络传输程序》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库

1、Linux环境下如何恰当的使用TCP协议编写网络传输程序【转】Linux环境下如何恰当的使用TCP协议编写网络传输程序2010-05-1108:55转载自xiangpengmeng最终编辑xiangpengmeng声明本文属于转载!学习中!!!摘要:本文介绍了Linux环境下TCP协议编写网络传输程序的几点考虑。作者提出了在使用此协议时,构造消息边界、区分程序控制数据与实际数据的设计思路。作者将客户与服务器之间的交互信息抽象成不同的命令,实现了一个文件传输协议和基于命令式交互的网络服务器、客户的架构模型。关键词:Linux,TCP,socket一、背景在2008年夏季小学期里,作者

2、学习了Linux的下的并发网络服务器的设计理论,根据老师的要求,编制了并发文件传输的服务器、客户端程序。在编写网络程序的过程中,作者考虑到了TCP协议的原理和一般网络环境的特点,提出了平时大家不太注意的几个问题,并给出了解决方案,实现了自己的文件传输协议。二、使用TCP协议编写文件传输程序的三个问题1、无法区分消息边界平时在谈论TCP时,我们都能够注意到它与UDP的一点区别,那就是TCP的传输是流式的,而UDP的传输是面向数据报的,但是一般的同学在第一次编写传输程序时,却没有意识到这一点。实际上,TCP的流式传输,体现在编程上,就是TCP不为应用程序保留消息边界。也就是说在一端调用

3、send(),发送一定的字节数,譬如2K个字节,在另一端调用recv()时,也许只收到其中的前1K个字节,需要再调用一次recv()才能把所有的字节收完整。这是因为在接收端的TCP程序收到合适数量的字节数之后或者缓存满之后,就会把缓冲区中的数据提交给应用程序,这时recv()函数返回,但实际上还有一些字节在网络上传送。若发送端调用两次send()分别发送了0.5K和2K个字节,接收端第一次接收可能会接收到1K个字节,第二次会接受到剩下的1.5K个字节。如果发送的0.5K和2K个字节分别代表服务器发送给客户的两个文件,接收方就无法区分两次收到的数据分别是哪个文件中的内容了。这种特点在

4、客户与服务器需要进行一定数量的交互应答时显得非常不方便,传送的消息全部杂糅在一起,区分不出边界,需要程序员自己处理边界的问题。2、不恰当的使用发送函数另外一个问题是一些同学使用循环,按一个字节一个字节的发送文件的内容,这样做是非常有害的。虽然程序把数据推送到缓冲区后,TCP会尽量把数据集合成MSS长度发送出去,但是若数据到达的速率比较慢,即使不到一个MSS的长度,TCP等待超过一段时间后,也会导致一次发送。另外,在关闭了Nagle算法后,这种一次要求TCP发送一个字节的函数调用的效率会更低,如果文件比较大,速度会慢得不能忍受。消费IP和TCP的较长头部,却只带走很少数量字节的净荷,

5、对带宽的利用率就变低了。3、控制信息与数据无法区分最后一个问题是,在文件较大的时候,无法一次全部读入内存,也无法一次就发送完毕,需要边读边发,这样就导致了多次send()函数的调用,客户与服务器进行请求应答会话时,传输的控制信息也要使用send(),由于没有消息边界,这些内容在recv()时就无法区分。在本次任务中,程序的要求比较简单,因此几乎没有控制信息,在更复杂的场合,这个问题是不可回避的。4、为什么平时都没有发现问题这些问题大家平时都不容易考虑到,是因为每次编写网络程序都比较简单,实验时也只发送小文件,看不到错误的发生。为了引发这些错误,我编写了一个程序,其逻辑很简单,先把文

6、件全部读到一个一维字节数组中,再一次调用send()函数全部发出去,在接收方调用一次recv()函数收取数据,再将数据写到文件中。这个程序在发送小文件时工作得很好,在发送一个2.1K的文件时,接收方只调用一次recv(),仅收到了1.4K,剩下的数据还留在接收方缓冲区中。三、文件传输程序的设计思路1、区分消息边界在链路层的协议中,区分消息边界用的是位填充与字符填充法。在本程序中,使用另外一种办法。不使用填充法是因为无论是字符填充还是位填充,都要扫描一遍所有的数据,寻找出与边界相冲突的模式。这在链路层是比较合理的,因为要计算桢检验信息,必然要做全部的扫描,这时就可以顺便找出冲突并进行

7、填充。但是在应用层的程序中,如果每次都要把所有的数据都扫描一遍,会减慢处理数据的速度。作者的办法是先发4字节定长的数据表示将来要发送的消息的长度,再一次把整个消息都推送给send()函数,放到缓冲区中,让TCP协议自己决定何时从缓冲区中取出数据、取多少数据发送到网络上。接收方每次先接收4字节的数据,确定将来接收数据的长度,根据这个信息,再不停的调用recv()函数,并累积已经收到的字节数,直到达到发送方一开始通告的数量为止。这期间收到的数据视为一个消息,下次再接收数据

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。