在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

應用層如何強制發送RST報文進行斷開連接呢

冬至子 ? 來源:Linux碼農 ? 作者:Linux碼農 ? 2022-11-16 17:53 ? 次閱讀

在 TCP 協議中,默認情況下,當我們調用 close() 函數關閉套接口時,TCP 走四次揮手進行斷開鏈路,但是要是若緩沖區還有數據未發送到對端時,系統將嘗試把這些數據發送給對端。四次揮手的過程導致我們在 TIME_WAIT 狀態下無法復用端口。有些情況下我們不需要 TIME_WAIT, 而是想快速斷開連接,從而避免 socket 的堆積。

這個時候我們可以使用 SO_LINGER 套接字選項

struct linger {
int l_onoff;
int l_linger;
}
  1. 若 l_onoff 為0, 表示關閉該選項。l_linger 值被忽略,也即是走TCP 的默認設置。

2)若 l_onoff 為非 0 且 l_linger 為 0,那么當 close 某個連接時 TCP 將終止該連接。也即是TCP將丟棄保留在套接字發送緩沖區中的任何數據,并發送RST報文給對端,不再走四次揮手,從而避免了 TCP 的 TIME_WAIT 狀態。但是依然存在以下可能性:在 2 MSL 秒內創建該連接的另一個化身,導致來自剛被終止的連接上的舊的重復分節被不正確的傳遞到新的化身上。

3)若 l_onoff 為非 0 值且 l_linger 也為非 0 值,那么當套接字關閉時內核將拖延一段時間關閉,也即是若在套接字的發送緩沖區中還有殘留數據,那么進程將投入睡眠,直到數據發送完且均被對端確認或者滯留時間到。若套接字被設置成非阻塞型,那么它將不等待 close 完成,即是滯留時間不為 0 也是如此。當使用 SO_LINGER 選項時,應用程序檢查 close 的返回值很重要,因為若在數據發送完并被確認前延滯時間到的話,close 將返回 EWOULDBLOCK 錯誤,且套接字發送緩沖區中的任何殘留數據都被丟棄。

通過下面實現進行驗證。

首先 server 端使用 nc 進行監聽一個TCP 指定端口。

客戶端使用如下代碼

#include          
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


int main(int argc, char *argv[])
{
    struct sockaddr_in peer;
    struct linger linger;
    int ret;
    int sock = socket(AF_INET, SOCK_STREAM, 0);

    memset(&peer, 0, sizeof(peer));

    peer.sin_family = AF_INET;
    inet_pton(AF_INET, argv[1], &peer.sin_addr);
    peer.sin_port = htons(atoi(argv[2])); 

    memset(&linger, 0, sizeof(linger));
    linger.l_onoff = 1;
    linger.l_linger = 0;

    ret = setsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger));
    if (ret) {
        printf("Fail to set linger\\n");
        exit(1);
    }

    ret = connect(sock, (const struct sockaddr *)&peer, sizeof(peer));

    if (ret) {
        printf("Fail to connect.\\n", strerror(errno));
        exit(1);
    }

    printf("Connect successfully\\n");



    close(sock);

    printf("Done\\n");

    return 0;
}

通過抓包分析來看,調用 close 后,客戶端直接發送了 RST 報文端開了連接。

19:22:13.101476 IP 17.15.220.199 > localhost.localdomain : Flags [S], seq 12771346 ..
19:22:13.101509 IP localhost.localdomain > 17.15.220.199 : Flags [S .], seq 1277234 ..
19:22:13.101732 IP 17.15.220.199 > localhost.localdomain : Flags [.], ack ...
19:22:13.101912 IP 17.15.220.199 > localhost.localdomain : Flags [R .] ...

在 tcp_close 中查看具體實現

/*
     內核并并不關心有多少數據未被用戶進程讀取,內核關心的是有沒有數據未被讀取,
     若有數據未被讀取而丟棄(data_was_unread>0),則給對方發送rst報文
     若沒有數據未被用戶進程讀取,也即是全部數據都被用戶進程讀取了(data_was_unread==0),則相對對端發送fin報文
    */
    if (data_was_unread) {
        /* Unread data was tossed, zap the connection. */
        NET_INC_STATS_USER(LINUX_MIB_TCPABORTONCLOSE);

        /*發送rst報文前設置狀態為TCP_CLOSE,這時沒有TIME_WAIT狀態,沒有FIN_WAIT_1狀態,說明此時時不正常關閉的。
        所以可得,在編寫程序時,在關閉連接前,一定要保證所有接收到的數據被讀取,否則連接會不正常關閉*/
        tcp_set_state(sk, TCP_CLOSE); 
        //發送rst報文,之所以不是fin報文,是因為關閉時還有未讀的數據屬于異常情況,fin表示一切正常情況
        tcp_send_active_reset(sk, GFP_KERNEL);
    } else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) {
        /* Check zero linger _after_ checking for unread data. */
        /*調用tcp_disconnect斷開、刪除并釋放已建立連接但未被accept的傳輸控制塊,同時
        刪除并釋放已接收在接收隊列(包括失序隊列)上的段以及發送隊列上的段*/
        sk->sk_prot->disconnect(sk, 0);// tcp_disconnect
        NET_INC_STATS_USER(LINUX_MIB_TCPABORTONDATA);
    } else if (tcp_close_state(sk)) { //若未讀字節數為0,則調用tcp_close_state根據sk當前狀態來設置sk下一狀態,比如當前狀態為TCP_ESTABLISHED,則下一狀態為TCP_FIN_WAIT1,該方法的返回確定是否發送fin報文給對方
        /*

從上面的代碼段可以看到,當有數據還未讀取時,說明是異常關閉,直接發送 RST 報文給對端。若接收緩沖區中數據都已經讀取完了,判斷 SOCK_LINGER 套接字選項,若 l_linger 為 0,則調用 tcp_disconnect 給對端發送 RST 報文,同時釋放接收和發送隊列上的數據。

審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • RST
    RST
    +關注

    關注

    0

    文章

    31

    瀏覽量

    7426
  • TCP協議
    +關注

    關注

    1

    文章

    101

    瀏覽量

    12127
收藏 人收藏

    評論

    相關推薦

    ESP32C6 WiFi報文出現大量重傳是什么原因導致的?

    與 STA的距離很近,不存在信號差的情況,請問可能是什么原因導致的? 此外,雖然應用層每隔100ms請求發一次WiFi報文,但從wireshark捕獲的報文看,報文
    發表于 06-06 07:55

    w5500 作為tcp server,客戶端異常發送RST,ACK】斷開連接問題

    測試1 w5500 作為tcp server,上位機labveiw程序作為clinet,正常第二次交互結束后,客戶端發送一個【RST,ACK】報文斷開
    發表于 10-14 14:01

    CC2540應用層的接受數據的buffer在哪

    CC2540應用層的接受數據的buffer在哪,因為,我想外擴CPU,需要做個透明傳輸。還望指點主從設備接受發送buffer分別在源程序哪里
    發表于 02-23 10:00

    14-TCP 協議(連接異常與RST

    release)。也可以通過發送 RST 段給對端來釋放連接,這種方式稱為異常釋放(abortive release)。異常終止連接有兩個特點:丟棄任何尚未
    發表于 07-24 10:01

    【學習打卡】OpenHarmony的應用層說明

    OpenHarmony的應用層包括系統應用和第三方非系統應用。什么是應用層應用層其實就是開放系統互連 ( OSI ) 通信模型的頂層。它確保應用程序可以有效地與不同計算機系統和網絡
    發表于 07-14 08:44

    CH582如何強制發送廣播?

    RT,原來使用PHY直接發,現在功能升級,使用了外設模式。通過廣播發送狀態,當狀態改變的時候如何強制發送?不然廣播間隔較長,要等到下次廣播。還有能否動態修改廣播長度?如
    發表于 08-01 07:52

    LWIP TCP報文基礎知識及其LWIP中TCP協議的實現

    接收完成后才將數據遞交到應用層。2 TCP 報文段結構TCP 報文段依賴 IP 協議進行發送,因此 TCP
    發表于 10-18 14:54

    tcp連接斷開連接圖解

    假設Client端發起中斷連接請求,也就是發送FIN報文。Server端接到FIN報文后,意思是說“我Client端沒有數據要發給你了”,但是如果你還有數據沒有
    發表于 12-08 13:53 ?1.5w次閱讀
    tcp<b class='flag-5'>連接</b>與<b class='flag-5'>斷開</b><b class='flag-5'>連接</b>圖解

    關于tcp協議棧中rst報文的seq跳變問題

    導致內核協議棧發送了一個rst報文,而rst報文選取seq的時候,并不是選取的確定已經發送的se
    的頭像 發表于 07-27 15:26 ?5099次閱讀
    關于tcp協議棧中<b class='flag-5'>rst</b><b class='flag-5'>報文</b>的seq跳變問題

    如何解釋TCP報文的內容

    TCP協議有著自己的數據包格式,這里把TCP的數據包稱為報文段(segment),TCP報文段封裝在IP數據報中發送,TCP報文段由TCP首部和TCP數據區組成,首部區域包含了
    的頭像 發表于 08-31 09:12 ?2880次閱讀

    為什么系統會自動回復RST報文

    從結果中可以看到 10.223.12.10 在接收到對端回應的 syn + ack 后,系統會自動給對端回應一個 RST 復位報文,導致二者的鏈路斷開
    的頭像 發表于 11-16 17:19 ?2089次閱讀

    應用層知多少?(總結在末尾)

    的語法、語義;進程何時、如何發送報?,以及對報?進?響應的規則。應用層功能與協議:域名服務:DNS;?件傳輸:FTP;電?郵件:SMTP、POP3;遠程登陸:TE
    的頭像 發表于 08-26 11:16 ?1463次閱讀
    <b class='flag-5'>應用層</b>知多少?(總結在末尾)

    物聯網的技術架構及應用層是什么?

    物聯網的技術架構包括感知、網絡、平臺應用層應用層是物聯網的頂層,它的主要功能是將感知
    的頭像 發表于 07-15 08:56 ?3832次閱讀

    基于TCP應用層協議

    ; 我們把攜帶RST標識的稱為復位報文段 SYN: 請求建立連接; 我們把攜帶SYN標識的稱為同步報文段 FIN: 通知對方, 本端要關閉了, 我們稱攜
    的頭像 發表于 11-11 11:23 ?1028次閱讀
    基于TCP<b class='flag-5'>應用層</b>協議

    CAN報文為什么會發送失敗?

    CAN總線調試過程中出現報文發送失敗。很多工程師都對此只知其一不知其二,今天我們就以CAN報文發送失敗的問題來做一次探討。在了解CAN報文
    的頭像 發表于 04-12 08:25 ?2314次閱讀
    CAN<b class='flag-5'>報文</b>為什么會<b class='flag-5'>發送</b>失敗?
    主站蜘蛛池模板: av大片| 伊人网站在线观看 | 欧美天天性影院 | 日韩精品毛片 | 一个色在线视频 | 天天射天天草 | 国产女人18毛片水真多18精品 | 在线看av网址| 欧美三级欧美一级 | 最近最新免费视频 | 韩国三级日本三级在线观看 | 欧美日本俄罗斯一级毛片 | 夜夜骑天天操 | 欧美一区二区三区不卡片 | 男女爱爱爽爽福利免费视频 | 人人澡人人添 | 九九热精品视频 | 亚洲 欧美 自拍 另类 欧美 | 永久免费mv网站入口 | 六月婷婷网视频在线观看 | 亚洲人色大成年网站在线观看 | 国产一区二卡三区四区 | 曰本裸色私人影院噜噜噜影院 | 手机看片久久青草福利盒子 | 亚洲精品在线免费观看视频 | 免看一级a毛片一片成人不卡 | 亚洲视频一区网站 | 国模论坛| 波多野结衣福利 | 最近2018中文字幕免费视频 | 拍拍拍无挡视频免费全程1000 | 一级毛片女人喷潮 | 白嫩少妇激情无码 | 美女污污网站 | 天天做天天爱天天做天天吃中 | 你懂得在线播放 | 欧美成人eee在线 | 亚洲精品网站日本xxxxxxx | 天天插天天干天天射 | 欧美人成绝费网站色www吃脚 | 亚洲第一毛片 |