久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 4018|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

TCP的OOS 隊(duì)列之胡猜亂猜胡師傅

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:82781 發(fā)表于 2015-6-13 00:41 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式


        最近忙于手頭工作,而沒(méi)有太多時(shí)間搞那懸而未決的OOS隊(duì)列斷言失敗的問(wèn)題。今晚猜測(cè)一下。
在測(cè)試中發(fā)現(xiàn)去掉這個(gè)隊(duì)列也是可以工作的,而且局域網(wǎng)內(nèi)也是不會(huì)丟包,所以這個(gè)OOS隊(duì)列的作用就有待審視。

要想搞清楚這個(gè)OOS對(duì)列斷言失敗的情況下這個(gè)隊(duì)列的作用首先要從他的誕生之地說(shuō)起。

IP層把數(shù)據(jù)交給tcp_input(struct pbuf *p, struct netif *inp),這就是開(kāi)始了。
接著‘
iphdr = p->payload;
  tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);
取出指向PBUF的載荷指針,就找到了那個(gè)所有的IP層運(yùn)輸?shù)腡CP數(shù)據(jù)包。于是乎又取走了TCP的首部,按照TCPIP協(xié)議加載到對(duì)應(yīng)的結(jié)構(gòu)中,這樣一個(gè)TCP頭的句柄就產(chǎn)生了。
接下來(lái)是縮減PBUF有效指針,移動(dòng)指針到拋去TCP首部的后邊TCP載荷數(shù)據(jù)上,這就是所謂的
pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr))
下一步是拋卻多播和廣播如果有,因?yàn)樵赥CP中這些完全是操蛋的玩意。邊去!
下一步校驗(yàn)這個(gè)TCP段是否正確。正確就繼續(xù)。

/* Convert fields in TCP header to host byte order. */
  tcphdr->src = ntohs(tcphdr->src);
  tcphdr->dest = ntohs(tcphdr->dest);
  seqno = tcphdr->seqno = ntohl(tcphdr->seqno);
  ackno = tcphdr->ackno = ntohl(tcphdr->ackno);
  tcphdr->wnd = ntohs(tcphdr->wnd);
顯然.........  那么。。。。
flags = TCPH_FLAGS(tcphdr);  tcplen = p->tot_len + ((flags & (TCP_FIN | TCP_SYN)) ? 1 : 0);
以上是取出來(lái)TCP的標(biāo)志,就是所謂的RST FIN....等等所在的字段,然后保存在一個(gè)全局變量flags中,這很重要。
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next)
開(kāi)始遍歷所有的活躍連接表。
如果活躍鏈表沒(méi)有,好開(kāi)始遍歷另一個(gè)
for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next)
就是所謂的等待隊(duì)列。
如果等待隊(duì)列也沒(méi)有再去遍歷另一個(gè)
for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next)
所謂的監(jiān)聽(tīng)列表,這就沒(méi)了。
如果當(dāng)前列表中有,那好(pcb != NULL)必定成立,則
inseg.next = NULL;
    inseg.len = p->tot_len;
    inseg.dataptr = p->payload;
    inseg.p = p;
    inseg.tcphdr = tcphdr;

    recv_data = NULL;
    recv_flags = 0;
開(kāi)始構(gòu)建TCP段準(zhǔn)備交付上層的結(jié)構(gòu)準(zhǔn)備工作。可見(jiàn)這個(gè)結(jié)構(gòu)繼承PBUF
緊接著執(zhí)行tcp_process(struct tcp_pcb *pcb)
開(kāi)始處理TCP事務(wù),其實(shí)是主要處理TCP的那狀態(tài)圖,根據(jù)
enum tcp_state {
  CLOSED      = 0,
  LISTEN      = 1,
  SYN_SENT    = 2,
  SYN_RCVD    = 3,
  ESTABLISHED = 4,
  FIN_WAIT_1  = 5,
  FIN_WAIT_2  = 6,
  CLOSE_WAIT  = 7,
  CLOSING     = 8,
  LAST_ACK    = 9,
  TIME_WAIT   = 10
};
這個(gè)狀態(tài)處理各個(gè)分支的枝枝叉叉。最后鎖定這個(gè)函數(shù)
tcp_receive(struct tcp_pcb *pcb)
這個(gè)函數(shù)開(kāi)始處理我兩件事3,一件事是TCP的ACK一件事是含有數(shù)據(jù)包的TCP報(bào)文。把它交給上層。但是他是如何交上去的,還得猜
if (flags & TCP_ACK) 這個(gè)就是處理TCP的ACK包,我們忽略這不是重點(diǎn),因?yàn)槲蚁肟纯吹讓訑?shù)據(jù)如何向上的。向下?lián)Q個(gè)選項(xiàng)
/* If the incoming segment contains data, we must process it
     further. */
  if (tcplen > 0) {。。。}
按照解釋上說(shuō)的是只做三件事:
/* This code basically does three things:

    +) If the incoming segment contains data that is the next
    in-sequence data, this data is passed to the application. This
    might involve trimming the first edge of the data. The rcv_nxt
    variable and the advertised window are adjusted.

    +) If the incoming segment has data that is above the next
    sequence number expected (->rcv_nxt), the segment is placed on
    the ->ooseq queue. This is done by finding the appropriate
    place in the ->ooseq queue (which is ordered by sequence
    number) and trim the segment in both ends if needed. An
    immediate ACK is sent to indicate that we received an
    out-of-sequence segment.

    +) Finally, we check if the first segment on the ->ooseq queue
    now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If
    rcv_nxt > ooseq->seqno, we must trim the first edge of the
    segment on ->ooseq before we adjust rcv_nxt. The data in the
    segments that are now on sequence are chained onto the
    incoming segment so that we only need to call the application
    once.
    */
終于出來(lái)OOS對(duì)列了,這個(gè)稱(chēng)之為:out-of-sequence 隊(duì)列。如上文所述
這個(gè)OOS是用來(lái)存儲(chǔ)失序的SEQ號(hào)所排的隊(duì),并且按照序號(hào)鏈接起來(lái)一并交付應(yīng)用層處理,這種失序在局域網(wǎng)中小數(shù)據(jù)根本沒(méi)有。只有
在廣域網(wǎng)中或或者在局域網(wǎng)高速數(shù)據(jù)吞吐的情況下才會(huì)發(fā)生,尤其是廣域網(wǎng)中這種情況完全可能,
TCP的失序問(wèn)題是這樣產(chǎn)生的
HOST端發(fā)送的數(shù)據(jù)經(jīng)過(guò)若干道路由,有可能有的去天津饒了一圈,有的去海南轉(zhuǎn)了圈,再回來(lái)肯定有時(shí)間差,時(shí)間差很可能會(huì)發(fā)生序號(hào)小的后到達(dá),而序號(hào)大的先到達(dá),這是完全有可能的,這是OOS隊(duì)列起作用了,他會(huì)緩存住失序的TCP段,并發(fā)出失序應(yīng)答。然后重新連接PBUF把序號(hào)鏈接的BUF連接重新分配后一并交付應(yīng)用層。

而現(xiàn)在回到我最初的問(wèn)題,那就是斷言失敗,在哪里斷言失敗呢,恰巧是在OOS對(duì)列的更新WIN處,也就是說(shuō)這個(gè)OOS還要關(guān)心一個(gè)TCP的滑動(dòng)窗口,而應(yīng)用層遲遲沒(méi)能從更新WIN,也就是沒(méi)有及時(shí)的取走應(yīng)用層的數(shù)據(jù),而導(dǎo)致了WIN數(shù)據(jù)的推遲更新,更在搞的是還有的正確的數(shù)據(jù)包擠壓在OOS中,最要命的是WIN值并不多了,然后
pcb->rcv_nxt += TCP_TCPLEN(cseg);
          ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n",
                      pcb->rcv_wnd >= TCP_TCPLEN(cseg));
          pcb->rcv_wnd -= TCP_TCPLEN(cseg);

          tcp_update_rcv_ann_wnd(pcb);
事故就不可避免的發(fā)生了,WIN值減到了負(fù)的!那是絕對(duì)不允許的。所以這里斷言失敗了。輸入了一個(gè)非法的值。這個(gè)值是TCP的滑動(dòng)窗口不能為負(fù)造成的。W其實(shí)根源在于WIN值不大,大的話(huà)就不會(huì)出現(xiàn)負(fù)值鳥(niǎo)!!!!也就不會(huì)斷言失敗。

這種情況發(fā)生在網(wǎng)卡驅(qū)動(dòng)速度慢,然后HOST快速發(fā)送的時(shí)候,出現(xiàn)。同樣的程序倘若放到一臺(tái)網(wǎng)卡快的就沒(méi)有這個(gè)問(wèn)題。
現(xiàn)在只能猜到這里。表面上是WIN的值為負(fù),實(shí)際上還有一些深層的背靜因素所左右。也從側(cè)面看到同樣的情況軟件情況下好的硬件就很重要了。

現(xiàn)在的用法是去掉OOS,這樣一來(lái)他就不會(huì)緩存失序的隊(duì)列,也就不會(huì)重新組裝底層的失序數(shù)據(jù)。肯定會(huì)丟失一些數(shù)據(jù)的。如果快速?gòu)V域網(wǎng)通信。

也許這是協(xié)議棧的BUG也許是我沒(méi)用精細(xì)。總之去掉OOS在網(wǎng)卡不是那么優(yōu)秀的情況下會(huì)帶來(lái)一些意外收獲哦!!!!總比斷言失敗好吧。這只是個(gè)開(kāi)始~~~~~~

最近面對(duì)伙計(jì)們關(guān)于未來(lái)的質(zhì)問(wèn)我確實(shí)心下慚愧,確實(shí)沒(méi)有什么成就,哎!狗屁一樣!簡(jiǎn)直是槽糕透了,不過(guò)好在胡猜亂猜胡師傅 表示只要他那啥。。一定那啥...即使不那啥..胡猜亂猜胡師傅也自己認(rèn)為很那啥了!

胡猜亂猜胡師傅老王頭!!!


20150129
日照比特





分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:82781 發(fā)表于 2015-6-13 00:41 | 只看該作者
        Send


1、對(duì)載荷進(jìn)行填充,填充目標(biāo)地址。校驗(yàn)等
2、SndState = STATE_M_TX_XMIT;激活發(fā)送,打開(kāi)發(fā)送接口驅(qū)動(dòng)PortEnable( FALSE, TRUE );
3、發(fā)送 /* check if we are finished. */
        if( SndBufferCount != 0 )
        {
            PortPutByte( ( CHAR )*pucMasterSndBufferCur );
            pucMasterSndBufferCur++;  /* next byte in sendbuffer. */
            SndBufferCount--;
        }
4、發(fā)送完畢,開(kāi)始判斷當(dāng)前是否廣播然后區(qū)別對(duì)待(打開(kāi)接受關(guān)閉發(fā)送,打開(kāi)接收就是要接受回應(yīng)的。)

/* If the frame is broadcast ,master will enable timer of convert delay,
             * else master will enable timer of respond timeout. */
            if ( xFrameIsBroadcast == TRUE )
            {
            vMBMasterPortTimersConvertDelayEnable( );
            }
            else
            {
            vMBMasterPortTimersRespondTimeoutEnable( );
            }

兩種情況都是開(kāi)啟定時(shí)器計(jì)時(shí)開(kāi)始,但是時(shí)間長(zhǎng)短不一樣而已。
5、關(guān)閉POLL。
6、開(kāi)始等待延時(shí)結(jié)束
7、延時(shí)完成回調(diào)函數(shù)激活
/* A frame was send finish and convert delay or respond timeout expired.
* If the frame is broadcast,The master will idle,and if the frame is not
* broadcast.Notify the listener process error.*/
向應(yīng)用程序報(bào)告當(dāng)前的情況,是廣播的話(huà)就是當(dāng)前延時(shí)結(jié)束,是發(fā)送的話(huà)就是沒(méi)有回應(yīng)應(yīng)該報(bào)錯(cuò)誤。這樣一個(gè)超時(shí)錯(cuò)誤響應(yīng)的就產(chǎn)生了
于是通過(guò)一個(gè)隊(duì)列接口通知應(yīng)用即可】】
PortEventPost(EV_MASTER_ERROR_PROCESS);
8、  關(guān)閉定時(shí)器,發(fā)送狀態(tài)重新回到        eSndState = STATE_M_TX_IDLE;


值得注意的是這是非正常情況,正常是
如果收到從機(jī)的回應(yīng)主機(jī)會(huì)立即關(guān)閉發(fā)送等待定時(shí)器,并重新標(biāo)定發(fā)送狀態(tài)為空閑
case STATE_M_RX_IDLE:
     PortTimersDisable( );
            eSndState = STATE_M_TX_IDLE;
這個(gè)是在接受文件中定義的!
就是這些
2015年3月15日
比特
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 自拍偷拍亚洲欧美 | 高清人人天天夜夜曰狠狠狠狠 | 欧美在线视频网 | 精品久久久久久久 | 最新日韩在线视频 | www.夜夜骑.com | 亚洲精品麻豆 | 欧美视频1| 一级在线观看 | 国产一级视频免费播放 | 国产精品久久久久国产a级 欧美日本韩国一区二区 | 涩涩鲁亚洲精品一区二区 | 亚洲巨乳自拍在线视频 | 日韩日韩日韩日韩日韩日韩日韩 | 国产精品一区二区在线 | 欧美黄色一级毛片 | 在线播放亚洲 | 久久一级| 欧美日产国产成人免费图片 | 一区二区亚洲 | 欧美三区 | 韩国电影久久 | 色婷婷精品久久二区二区蜜臂av | 久草青青草 | 午夜精品久久久久久久 | 久久高清国产视频 | 交专区videossex农村 | 国产第一亚洲 | 国产美女在线看 | 精品日韩一区二区 | 91伦理片 | 久久综合伊人 | 欧美成人a∨高清免费观看 色999日韩 | 中文字幕免费视频 | 国产草草视频 | 国产精品无码永久免费888 | 欧美日韩在线一区二区 | 一本色道精品久久一区二区三区 | 久久久久久九九九九 | 红桃视频一区二区三区免费 | 久久久久国产一区二区三区 |