轉(zhuǎn)到SEND_ACK狀態(tài)發(fā)送數(shù)據(jù)應(yīng)答包; 4) SEND_ACK:如果接收數(shù)據(jù)的CRC錯(cuò)誤或者是達(dá)到了應(yīng)答包發(fā)送條件狀態(tài)機(jī)跳轉(zhuǎn)到 該狀態(tài)啟動(dòng)數(shù)據(jù)應(yīng)答包的發(fā)送。該狀態(tài)只持續(xù)一個(gè)時(shí)鐘周期,然后狀態(tài)機(jī)自動(dòng)跳轉(zhuǎn)到RCV_ IDLE狀態(tài)等待下一個(gè)數(shù)據(jù)包的接收。
[0032] 上述的接收控制狀態(tài)機(jī)為第二級(jí)狀態(tài)機(jī),只有當(dāng)主控制狀態(tài)機(jī)處于C0NN_EST狀 態(tài)時(shí)該狀態(tài)機(jī)才開(kāi)始工作。如果主控制狀態(tài)機(jī)跳出C0NN_EST狀態(tài)該狀態(tài)機(jī)會(huì)無(wú)條件的跳 轉(zhuǎn)到RCV_IDLE狀態(tài)。
[0033] 3.TCP數(shù)據(jù)發(fā)送控制是由TCP模塊8中的TCP發(fā)送引擎83實(shí)現(xiàn)的。設(shè)計(jì)中是通過(guò) 發(fā)送控制狀態(tài)機(jī)來(lái)控制發(fā)送的動(dòng)作。該狀態(tài)機(jī)的狀態(tài)轉(zhuǎn)移圖如圖6所示,狀態(tài)說(shuō)明和跳轉(zhuǎn) 條件說(shuō)明如下 : 1)SEND_IDLE:空閑狀態(tài)。當(dāng)需要發(fā)送的數(shù)據(jù)準(zhǔn)備好并且發(fā)送窗口(發(fā)送窗口的大小和 接收端接收窗口剩余的空間以及還沒(méi)有應(yīng)答的數(shù)據(jù)的長(zhǎng)度相關(guān))大于本次發(fā)送的數(shù)據(jù)包長(zhǎng) 度(圖中的JPC表示的狀態(tài)機(jī)跳轉(zhuǎn)條件)時(shí)跳轉(zhuǎn)到SEND_DATA狀態(tài)開(kāi)始發(fā)送數(shù)據(jù); 2) SEND_DATA:發(fā)送數(shù)據(jù)狀態(tài)。其主要的動(dòng)作是生成TCP數(shù)據(jù)包的包頭,每一次TCP數(shù) 據(jù)包的發(fā)送其包頭內(nèi)需要變更的是序列號(hào)、應(yīng)答序列號(hào)和CRC值。其中序列號(hào)是根據(jù)發(fā)送 數(shù)據(jù)計(jì)數(shù)器得到的,表示已經(jīng)發(fā)送的數(shù)據(jù)字節(jié)的個(gè)數(shù);應(yīng)答序列號(hào)的更新是在發(fā)送合成復(fù) 用模塊85里完成的,在TCP發(fā)送引擎內(nèi)不會(huì)對(duì)其進(jìn)行操作;CRC值的生成首先需要從數(shù)據(jù) 接口引擎9里讀出需要發(fā)送的數(shù)據(jù)的CRC,然后加上包頭內(nèi)其他參數(shù)的值。TCP數(shù)據(jù)包的包 頭會(huì)放入TCP包頭緩沖,然后通知IP模塊有TCP數(shù)據(jù)包需要發(fā)送。這些動(dòng)作完成之后狀態(tài) 機(jī)跳轉(zhuǎn)到SEND_WAIT狀態(tài); 3)SEND_WAIT:發(fā)送的中間等待狀態(tài)。如果JPC條件滿(mǎn)足狀態(tài)機(jī)跳轉(zhuǎn)到SEND_DATA狀態(tài) 繼續(xù)發(fā)送數(shù)據(jù);如果接收到數(shù)據(jù)應(yīng)答包或應(yīng)答包接收超時(shí)狀態(tài)機(jī)跳轉(zhuǎn)到ACK_T0_0PT狀態(tài); 4) ACK_T0_0PT:應(yīng)答和超時(shí)處理狀態(tài),該狀態(tài)內(nèi)會(huì)啟動(dòng)應(yīng)答和超時(shí)狀態(tài)機(jī)對(duì)應(yīng)答和超 時(shí)做處理。如果JPC條件滿(mǎn)足狀態(tài)機(jī)跳轉(zhuǎn)到SEND_DATA狀態(tài)繼續(xù)發(fā)送數(shù)據(jù)。
[0034] 上述的發(fā)送控制狀態(tài)機(jī)是和接收控制狀態(tài)機(jī)并行操作的第二級(jí)狀態(tài)機(jī),同樣只有 當(dāng)主控制狀態(tài)機(jī)處于C0NN_EST狀態(tài)時(shí)該狀態(tài)機(jī)才開(kāi)始工作。如果主控制狀態(tài)機(jī)跳出C0NN_EST狀態(tài)該狀態(tài)機(jī)會(huì)無(wú)條件的跳轉(zhuǎn)到SEND_IDLE狀態(tài)。
[0035] 4.在TCP傳輸過(guò)程中會(huì)因?yàn)榫W(wǎng)絡(luò)擁塞、傳輸錯(cuò)誤或接收端緩沖區(qū)溢出等問(wèn)題造成 TCP數(shù)據(jù)包的丟失,當(dāng)丟包發(fā)生時(shí)在傳輸端的表現(xiàn)是收不到應(yīng)答包或是收到多次重復(fù)的應(yīng) 答包,這就是TCP協(xié)議中定義的超時(shí)。當(dāng)超時(shí)發(fā)生時(shí)需要有一種簡(jiǎn)單高效的重傳機(jī)制來(lái)恢 復(fù)。
[0036]對(duì)超時(shí)的判斷需要一個(gè)往返時(shí)間超時(shí)門(mén)限,本發(fā)明中使用兩種方式得到該門(mén)限 值: 1) 固定門(mén)限值,上位機(jī)配置一個(gè)固定值作為超時(shí)門(mén)限值。這種方式使用在網(wǎng)絡(luò)拓?fù)浣Y(jié) 構(gòu)比較簡(jiǎn)單,要求高速傳輸?shù)沫h(huán)境下; 2)TCP協(xié)議中介紹的往返時(shí)間測(cè)量方法,也就是Jacobson1988中定義的算法,基于均 值和方差來(lái)計(jì)算往返時(shí)間。其實(shí)現(xiàn)公式如下: Err=M- A=A, +g*Err D=D,+h* (|Err|_D,) RT0=A+ 4D 其中M是本次測(cè)量的往返時(shí)間、A和A'是被平滑的均值估計(jì)器,帶上標(biāo)的表示上一次 計(jì)算的結(jié)果、D和D'是平滑的均值誤差,同樣帶上標(biāo)的表示上一次的結(jié)果、Err為本次測(cè)量 結(jié)果與上一次的均值估計(jì)器之差、增量g起平均作用,取值為0. 125、偏差的增益是h,取值 為0. 25、RT0為下一次超時(shí)門(mén)限。
[0037]根據(jù)上面的算法可知,每一次測(cè)量往返之間之后都會(huì)對(duì)超時(shí)門(mén)限進(jìn)行修改,以確 保超時(shí)門(mén)限和實(shí)際的網(wǎng)絡(luò)延時(shí)匹配,不會(huì)引起不必要的重傳。另外在TCP協(xié)議中測(cè)量的時(shí) 間單位為秒,在本發(fā)明中用時(shí)鐘周期作為計(jì)量單位,這樣使得實(shí)現(xiàn)更加簡(jiǎn)單。
[0038]另外對(duì)每次收到的應(yīng)答包的包頭中的應(yīng)答序號(hào)進(jìn)行判斷,在本發(fā)明中如果連續(xù)收 到三次相同序號(hào)的應(yīng)答包也判斷為傳輸過(guò)程中有丟包的情況發(fā)生。
[0039]在TCP協(xié)議中使用快速重傳和快速恢復(fù)算法對(duì)超時(shí)和重傳進(jìn)行操作。該算法易于 用軟件的方式實(shí)現(xiàn),對(duì)硬件實(shí)現(xiàn)而言實(shí)現(xiàn)過(guò)于復(fù)雜。本發(fā)明中如果丟包的情況發(fā)生,就重傳 丟失的數(shù)據(jù)包然后等待接收端對(duì)丟失的數(shù)據(jù)包做出應(yīng)答,在此過(guò)程中不發(fā)送新的數(shù)據(jù)包以 免引起更多的丟包。在千兆網(wǎng)絡(luò)的實(shí)際測(cè)試中,測(cè)試結(jié)果如下:
從上表所示的測(cè)試結(jié)果表明使用本發(fā)明的算法數(shù)據(jù)包重傳的比例會(huì)小于使用快速重 傳和恢復(fù)算法。傳輸速率在丟包率小于1%的情況下與快速重傳和恢復(fù)算法相當(dāng),只有當(dāng)丟 包率大于2%時(shí)傳輸速率才有明顯的下降,但是丟包率大于1%已經(jīng)是非常極限的情況了。所 以本發(fā)明使用的重傳算法完全能滿(mǎn)足正常的網(wǎng)絡(luò)環(huán)境下傳輸?shù)男枨蟆?br>[0040] 本發(fā)明使用超時(shí)和應(yīng)答操作狀態(tài)機(jī)來(lái)控制應(yīng)答包的處理和重傳操作,。該狀態(tài)機(jī) 的狀態(tài)轉(zhuǎn)移圖如圖7所示,狀態(tài)說(shuō)明和跳轉(zhuǎn)條件說(shuō)明如下: 1) AT0_IDLE:空閑狀態(tài),狀態(tài)機(jī)默認(rèn)狀態(tài)。只有當(dāng)發(fā)送控制狀態(tài)機(jī)處于AT0_T0_0PT狀 態(tài)時(shí)超時(shí)和應(yīng)答操作狀態(tài)機(jī)才會(huì)判斷跳轉(zhuǎn)條件做相應(yīng)的跳轉(zhuǎn)操作; 2) AT0_RESEND:超時(shí)或收到三次相同的應(yīng)答包并且發(fā)送狀態(tài)機(jī)處于ACK_T0_ACK狀態(tài) 時(shí)狀態(tài)機(jī)由AT0_IDLE跳轉(zhuǎn)到該狀態(tài)。在該狀態(tài)會(huì)重傳丟失的數(shù)據(jù)包。重傳之后狀態(tài)機(jī)停 在該狀態(tài)等待應(yīng)答包,如果又出現(xiàn)了超時(shí)狀態(tài)機(jī)會(huì)跳轉(zhuǎn)到AT0_IDLE狀態(tài),如果接收到應(yīng)答 包并且應(yīng)答包的序列號(hào)大于重傳數(shù)據(jù)包的序列號(hào),表示接收端對(duì)當(dāng)當(dāng)發(fā)送的重傳的數(shù)據(jù)包 做出了應(yīng)答,狀態(tài)機(jī)跳轉(zhuǎn)到AT0_ACK_0PT狀態(tài); 3) AT0_ACK_0PT:該狀態(tài)不做具體的操作,只持續(xù)一個(gè)時(shí)鐘周期。定義該狀態(tài)的目的是 把該狀態(tài)作為時(shí)間分割點(diǎn),在狀態(tài)跳轉(zhuǎn)的過(guò)程中修改相應(yīng)的發(fā)送控制和狀態(tài)寄存器的值。 在該狀態(tài)如果收到三次相同應(yīng)答包的指示信號(hào)有效狀態(tài)機(jī)跳轉(zhuǎn)到AT0_RESEND狀態(tài)啟動(dòng)重 傳操作,否則狀態(tài)機(jī)跳轉(zhuǎn)到AT0_IDLE狀態(tài)。
[0041] 超時(shí)和應(yīng)答操作狀態(tài)機(jī)是和發(fā)送控制狀態(tài)機(jī)并行操作的第二級(jí)狀態(tài)機(jī),這兩個(gè)狀 態(tài)機(jī)配合完成TCP的發(fā)送操作。比如在發(fā)送控制狀態(tài)機(jī)處于SEND_DATA狀態(tài)正在發(fā)送數(shù)據(jù) 包的過(guò)程中接收到應(yīng)答包,應(yīng)答包的應(yīng)答序列號(hào)為X,而該應(yīng)答包已經(jīng)是接收到的第三個(gè)相 同的應(yīng)答包,此時(shí)會(huì)使應(yīng)答包接收指示信號(hào)和接收三次相同應(yīng)答包指示信號(hào)同時(shí)有效。數(shù) 據(jù)包頭準(zhǔn)備好并且啟動(dòng)發(fā)送之后發(fā)送控制狀態(tài)機(jī)會(huì)跳轉(zhuǎn)到SEND_WAIT狀態(tài)。在SEND_WAIT 狀態(tài)因?yàn)閼?yīng)答包接收指示信號(hào)有效,發(fā)送控制狀態(tài)機(jī)跳轉(zhuǎn)到ACK_T0_0PT狀態(tài)處理應(yīng)答包。 因?yàn)閼?yīng)答包接收指示信號(hào)有效,超時(shí)和重傳狀態(tài)機(jī)會(huì)跳轉(zhuǎn)到AT0_ACK_0PT,又因?yàn)榻邮杖?相同應(yīng)答包指示信號(hào)有效,會(huì)直接從AT0_ACK_0PT跳轉(zhuǎn)到AT0_RESEND狀態(tài)啟動(dòng)重傳操作。 進(jìn)入該狀態(tài)會(huì)修改發(fā)送窗口的值,使其等于重傳數(shù)據(jù)包的長(zhǎng)度。如果待重傳的數(shù)據(jù)準(zhǔn)備好, 那么JPC跳轉(zhuǎn)條件滿(mǎn)足,發(fā)送控制狀態(tài)機(jī)會(huì)跳轉(zhuǎn)到SEND_DATA狀態(tài),發(fā)送序列號(hào)為X+1的數(shù) 據(jù)包。完成了丟失的數(shù)據(jù)包的重傳操作。
[0042] 5.滑動(dòng)窗的處理和擁塞避免的實(shí)現(xiàn)是TCP實(shí)現(xiàn)中非常重要的部分。滑動(dòng)窗口協(xié)議 是接收方通過(guò)TCP頭的窗口大小字段通知發(fā)送方接收端可用的接收緩沖的大?。粨砣苊?的目的是當(dāng)出現(xiàn)網(wǎng)絡(luò)擁塞的時(shí)候降低數(shù)據(jù)包進(jìn)入網(wǎng)絡(luò)的傳輸速率以免造成更大的擁塞。
[0043] TCP協(xié)議中定義了擁塞避免算法對(duì)其進(jìn)行處理,本發(fā)明中使用更加嚴(yán)格的擁塞避 免算法使其更加適應(yīng)各種網(wǎng)絡(luò)情況。算法的工作過(guò)程如下: 1)對(duì)一個(gè)新的連接,初始化發(fā)送窗口send_wnd的大小為連接建立過(guò)程中接收端回復(fù) 的應(yīng)答包頭字段中窗口大小的值; 2)如果sencLwnd大于本次傳輸?shù)臄?shù)據(jù)長(zhǎng)度,啟動(dòng)數(shù)據(jù)包的發(fā)送操作; 3)發(fā)送一個(gè)數(shù)據(jù)包之后,sencLwnd需要減去本次發(fā)送的數(shù)據(jù)包長(zhǎng)度; 4)每次收到接收端的應(yīng)答包都會(huì)更新sencUnd的值。更新方式為,用已經(jīng)發(fā)送的數(shù) 據(jù)序號(hào)sended_data_number減去已經(jīng)應(yīng)答的數(shù)據(jù)序號(hào)acked_data_number得到未應(yīng)答的 數(shù)據(jù)長(zhǎng)度noack_data_len。然后比較接收窗口rcv_wnd和noack_data_len,如果noack_ data_len大于rcv_wnd,send_wnd賦值為0不啟動(dòng)新的傳輸,否則send_wnd賦值為noack_ data_len與rcv_wnd之差。這樣就保證了不會(huì)因?yàn)榻邮沾翱谝绯鰧?dǎo)致更多的擁塞; 5)當(dāng)擁塞發(fā)生時(shí)(超時(shí)或接收到重復(fù)確認(rèn)),sencLwnd被設(shè)置為重傳的數(shù)據(jù)包的長(zhǎng)度, 僅發(fā)送重傳包。當(dāng)重傳的數(shù)據(jù)包得到應(yīng)答后按照第4步操作。
[0044] 上述的擁塞避免算法需要對(duì)每個(gè)連接維持一組發(fā)送控制和狀態(tài)寄存器。寄存器的 說(shuō)明和更新的時(shí)間如下表所示:
五、為了提高TCP發(fā)送的速率,在數(shù)據(jù)包發(fā)送之前數(shù)據(jù)需要從存取速度相對(duì)比較慢的 外部存儲(chǔ)器中緩存入存取速度和處理速度匹配的內(nèi)部存儲(chǔ)器中。本發(fā)明中該功能使用數(shù)據(jù) 多級(jí)緩存和高效預(yù)取技術(shù)來(lái)完成。具體體現(xiàn)在數(shù)據(jù)交互引擎9的發(fā)送數(shù)據(jù)通道94的設(shè)計(jì) 中。
[0045] 在設(shè)計(jì)中使用容量比較大的發(fā)送FIFO作為發(fā)送數(shù)據(jù)的第一級(jí)緩存,只要是外部 存儲(chǔ)器中有需要發(fā)送的數(shù)據(jù),讀寫(xiě)訪(fǎng)問(wèn)控制模塊92就啟動(dòng)預(yù)取操作從外部存儲(chǔ)器中讀出 數(shù)據(jù)放入發(fā)送FIFO中。當(dāng)判斷到發(fā)送FIFO中有數(shù)據(jù)后,發(fā)送BUF寫(xiě)狀態(tài)機(jī)會(huì)控制數(shù)據(jù)從發(fā) 送FIFO中讀出然后寫(xiě)入到發(fā)送BUFA和BUFB中,在寫(xiě)入的過(guò)程中會(huì)計(jì)算數(shù)據(jù)的CRC值,在 數(shù)據(jù)寫(xiě)入完成之后把CRC值也寫(xiě)入到發(fā)送緩沖器中。兩個(gè)發(fā)送緩沖器組成一組乒乓緩沖, 交互的操作,BUFA寫(xiě)入完成之后寫(xiě)入BUFB,然后等待BUFA的數(shù)據(jù)被讀出之后再次把數(shù)據(jù)寫(xiě) 入到BUFA。這兩個(gè)發(fā)送緩沖器作為發(fā)送數(shù)據(jù)的第二級(jí)緩存。
[0046] 另外如果是重傳操作,重傳BUF控制狀態(tài)機(jī)會(huì)從外部存儲(chǔ)器中讀出需要重傳的數(shù) 據(jù)直接寫(xiě)入到重傳BUF中。因?yàn)橹貍鞯臄?shù)據(jù)是少量和隨機(jī)的,所以只使用了一級(jí)緩沖。
[0047] 當(dāng)上述的重傳BUF、發(fā)送BUFA和發(fā)送BUFB中的數(shù)據(jù)準(zhǔn)備好之后就通過(guò)三個(gè)比特的 數(shù)據(jù)準(zhǔn)備好信號(hào)通知TCP模塊進(jìn)行發(fā)送。開(kāi)始發(fā)送之后,數(shù)據(jù)交互邏輯根據(jù)本次發(fā)送是否 為重發(fā)操作以及緩沖器選擇信號(hào)選擇TCP模塊對(duì)CRC的讀取操作和組包