请教:关于TCP接收乱序问题
在学习socket过程中,近日遇到一个很头疼的问题,苦想了两天还是没有什么头绪。
在使用TCP协议时,接收端收到的数据发生了乱序想象。
TCP定义: 作为一个面向连接的传输层协议,TCP的目标是为用户提供可靠的端到端连接,保证信息有序无误的传输。它除了提供基本的数据传输功能外,还为保证可靠性采用了数据编号、校验和计算、数据确认等一系列措施。它对传送的每个数据字节都进行编号,并请求接收方回传确认信息(ack)。发送方如果在规定的时间内没有收到数据确认,就重传该数据。数据编号使接收方能够处理数据的失序和重复问题。数据误码问题通过在每个传输的数据段中增加校验和予以解决,接收方在接收到数据后检查校验和,若校验和有误,则丢弃该有误码的数据段,并要求发送方重传。流量控制也是保证可靠性的一个重要措施,若无流控,可能会因接收缓冲区溢出而丢失大量数据,导致许多重传,造成网络拥塞恶性循环。TCP采用可变窗口进行流量控制,由接收方控制发送方发送的数据量。
因此TCP连接应该保证,所接收的数据先来先到,并有序排列。这情况在写文件时得到了验证,但在内存中却出现了乱序想象。
这是两者的对比:
写入文本的数据:
<Msg><memoid>2402</memoid><title>ddd</title><text>ddd</text><hdate>2007-08-25 15:00:16</hdate><operdate>2007-08-23 15:00:22</operdate><end>AHEAD</end></Msg>
<Msg><memoid>2403</memoid><title>ddd</title><text>ddd</text><hdate>2007-08-25 15:00:16</hdate><operdate>2007-08-23 15:00:25</operdate><end>AHEAD</end></Msg>
<Msg><memoid>2405</memoid><title>f</title><text>f</text><hdate>2007-08-25 15:00:16</hdate><operdate>2007-08-23 15:00:30</operdate><end>AHEAD</end></Msg>
<Msg><memoid>2593</memoid><title>ss</title><text>ss</text><hdate>2007-08-24 11:34:00</hdate><operdate>2007-08-24 11:33:54</operdate><end>AHEAD</end></Msg>
<Msg><memoid>2594</memoid><title>gg</title><text>gg</text><hdate>2007-08-25 11:43:38</hdate><operdate>2007-08-24 11:48:01</operdate><end>AHEAD</end></Msg>
<Msg><memoid>2596</memoid><title>gg</title><text>gg</text><hdate>2007-08-25 11:43:38</hdate><operdate>2007-08-24 11:48:07</operdate><end>AHEAD</end></Msg>
<Msg><memoid>2597</memoid><title>gg</title><text>gg</text><hdate>2007-08-25 11:43:38</hdate><operdate>2007-08-24 11:48:10</operdate><end>AHEAD</end></Msg>
<Msg><memoid>2601</memoid><title>ggddddddddddddddddddd</title><text>gg</text><hdate>2007-08-25 11:43:38</hdate><operdate>2007-08-24 15:12:47</operdate><end>AHEAD</end></Msg>
<Msg><memoid>2602</memoid><title>12</title><text>fddfg</text><hdate>2007-08-30 15:38:42</hdate><operdate>2007-08-24 15:39:15</operdate><end>AHEAD</end></Msg>
<Msg><end>END</end></Msg>
存放于内存的数据:
<Msg><memoid>2402</memoid><title>ddd</title><text>ddd</text><hdate>2007-08-25 15:00:16</hdate><operdate>2007-08-23 15:00:22</operdate><end>AHEAD</end></Msg>
<Msg><memoid>2403</memoid><title>ddd</title><text>ddd</text><hdate>2007-08-25 15:00:16</hdate><operdate>2007-08-23 15:00:25</operdate><end>AHEAD</end></Msg>
<Msg><memoid>2405</memoid><title>f</title><text>f</text><hdate>2007-08-25 15:00:16</hdate><operdate>2007-08-23 15:00:30</operdate><end>AHEAD</end></Msg>
<Msg><memoid>2593</memoid><title>ss</title><text>ss</text><hdate>2007-08-24 11:34:00</hdate><operdate>2007-08-24 11:33:54</operdate><end>AHEAD</end></Msg>
<Msg><memoid>2594</memoid><title>gg</title><text>gg</text><hdate>2007-08-25 11:43:38</hdate><operdate>2007-08-24 11:48:01</operdate><end>AHEAD</end></Msg>
<Msg><memoid>2596</memoid><title>gg</title><text>gg</text><hdate>2007-08-25 11:43:38</hdate><operdate>2007-08-24 11:48:07</operdate><end>AHEAD</end></Msg>
<Msg><memoid>2597</memoid><title>gg</title><text>gg</text><hdate>2007-08-25 11:43:38</hdate><operdate>2007-08-24 11:48:10</operdate><end>AHEAD</end></Msg>
<Msg><memoid>2601</memoid><title>ggddddddddddddddddddd</title><text>gg</text><hdate>2007-08-25 11:43:38</hdate><operdate>2007-08-24 15:12:47</operdate><end>AHEAD</end></Msg>
<Msg><memoid>2602</memoid><title>12</title><text>fddfg</text><hdate>2007-08-30 15:38:42</hdate><operdate>2007-08-24 15:39:15</operdate><end>AHEAD</end></Msg>
<Msg><end>EN2007-08-23 15:00:30</operdate><end>AHEAD</end></Msg>
<Msg><memoid>2593</memoid><title>ss</title><text>ss</text><hdate>2007-08-24 11:34:00</hdate><operdate>2007-08-24 11:33:54</operdate><end>AHEAD</end></Msg>
<Msg><memoid>2594</memoid><title>gg</title><text>gg</text><hdate>2007-08-25 11:43:38</hdate><operdate>2007-08-24 11:48:01</operdate><end>AHEAD</end></Msg>
<Msg><memoid>2596</memoid><title>gg</title><text>gg</text><hdate>2007-08-25 11:43:38</hdate><operdate>2007-08-24 11:48:07</operdate><end>AHEAD</end></Msg>
<Msg><memoid>2597</memoid><title>gg</title><text>gg</text><hdate>2007-08-25 11:43:38</D</end></Msg>
实现的代码:
while(true)
{
leng = m_pSocket->Receive(chrBuff, 1024);
file.Seek(0, CFile::end);
file.Write(chrBuff, leng);//写文本
strbuff += chrBuff; //内存存放
}
//判断结束及回收部分省略
很明显ID 为2593~2597的数据发生了重传,写入文本的部分遵循排序,而内存数据发生乱序。
望高手解答。!!!!!!!