色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

應(yīng)用層如何強(qiáng)制發(fā)送RST報(bào)文進(jìn)行斷開連接呢

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

在 TCP 協(xié)議中,默認(rèn)情況下,當(dāng)我們調(diào)用 close() 函數(shù)關(guān)閉套接口時(shí),TCP 走四次揮手進(jìn)行斷開鏈路,但是要是若緩沖區(qū)還有數(shù)據(jù)未發(fā)送到對(duì)端時(shí),系統(tǒng)將嘗試把這些數(shù)據(jù)發(fā)送給對(duì)端。四次揮手的過程導(dǎo)致我們?cè)?TIME_WAIT 狀態(tài)下無法復(fù)用端口。有些情況下我們不需要 TIME_WAIT, 而是想快速斷開連接,從而避免 socket 的堆積。

這個(gè)時(shí)候我們可以使用 SO_LINGER 套接字選項(xiàng)

struct linger {
int l_onoff;
int l_linger;
}
  1. 若 l_onoff 為0, 表示關(guān)閉該選項(xiàng)。l_linger 值被忽略,也即是走TCP 的默認(rèn)設(shè)置。

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

3)若 l_onoff 為非 0 值且 l_linger 也為非 0 值,那么當(dāng)套接字關(guān)閉時(shí)內(nèi)核將拖延一段時(shí)間關(guān)閉,也即是若在套接字的發(fā)送緩沖區(qū)中還有殘留數(shù)據(jù),那么進(jìn)程將投入睡眠,直到數(shù)據(jù)發(fā)送完且均被對(duì)端確認(rèn)或者滯留時(shí)間到。若套接字被設(shè)置成非阻塞型,那么它將不等待 close 完成,即是滯留時(shí)間不為 0 也是如此。當(dāng)使用 SO_LINGER 選項(xiàng)時(shí),應(yīng)用程序檢查 close 的返回值很重要,因?yàn)槿粼跀?shù)據(jù)發(fā)送完并被確認(rèn)前延滯時(shí)間到的話,close 將返回 EWOULDBLOCK 錯(cuò)誤,且套接字發(fā)送緩沖區(qū)中的任何殘留數(shù)據(jù)都被丟棄。

通過下面實(shí)現(xiàn)進(jìn)行驗(yàn)證。

首先 server 端使用 nc 進(jìn)行監(jiān)聽一個(gè)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;
}

通過抓包分析來看,調(diào)用 close 后,客戶端直接發(fā)送了 RST 報(bào)文端開了連接。

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 中查看具體實(shí)現(xiàn)

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

        /*發(fā)送rst報(bào)文前設(shè)置狀態(tài)為TCP_CLOSE,這時(shí)沒有TIME_WAIT狀態(tài),沒有FIN_WAIT_1狀態(tài),說明此時(shí)時(shí)不正常關(guān)閉的。
        所以可得,在編寫程序時(shí),在關(guān)閉連接前,一定要保證所有接收到的數(shù)據(jù)被讀取,否則連接會(huì)不正常關(guān)閉*/
        tcp_set_state(sk, TCP_CLOSE); 
        //發(fā)送rst報(bào)文,之所以不是fin報(bào)文,是因?yàn)殛P(guān)閉時(shí)還有未讀的數(shù)據(jù)屬于異常情況,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. */
        /*調(diào)用tcp_disconnect斷開、刪除并釋放已建立連接但未被accept的傳輸控制塊,同時(shí)
        刪除并釋放已接收在接收隊(duì)列(包括失序隊(duì)列)上的段以及發(fā)送隊(duì)列上的段*/
        sk->sk_prot->disconnect(sk, 0);// tcp_disconnect
        NET_INC_STATS_USER(LINUX_MIB_TCPABORTONDATA);
    } else if (tcp_close_state(sk)) { //若未讀字節(jié)數(shù)為0,則調(diào)用tcp_close_state根據(jù)sk當(dāng)前狀態(tài)來設(shè)置sk下一狀態(tài),比如當(dāng)前狀態(tài)為TCP_ESTABLISHED,則下一狀態(tài)為TCP_FIN_WAIT1,該方法的返回確定是否發(fā)送fin報(bào)文給對(duì)方
        /*

從上面的代碼段可以看到,當(dāng)有數(shù)據(jù)還未讀取時(shí),說明是異常關(guān)閉,直接發(fā)送 RST 報(bào)文給對(duì)端。若接收緩沖區(qū)中數(shù)據(jù)都已經(jīng)讀取完了,判斷 SOCK_LINGER 套接字選項(xiàng),若 l_linger 為 0,則調(diào)用 tcp_disconnect 給對(duì)端發(fā)送 RST 報(bào)文,同時(shí)釋放接收和發(fā)送隊(duì)列上的數(shù)據(jù)。

審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • RST
    RST
    +關(guān)注

    關(guān)注

    0

    文章

    31

    瀏覽量

    7402
  • TCP協(xié)議
    +關(guān)注

    關(guān)注

    1

    文章

    91

    瀏覽量

    12078
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    ESP32C6 WiFi報(bào)文出現(xiàn)大量重傳是什么原因?qū)е碌模?/a>

    與 STA的距離很近,不存在信號(hào)差的情況,請(qǐng)問可能是什么原因?qū)е碌模?此外,雖然應(yīng)用層每隔100ms請(qǐng)求發(fā)一次WiFi報(bào)文,但從wireshark捕獲的報(bào)文看,報(bào)文
    發(fā)表于 06-06 07:55

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

    測(cè)試1 w5500 作為tcp server,上位機(jī)labveiw程序作為clinet,正常第二次交互結(jié)束后,客戶端發(fā)送一個(gè)【RST,ACK】報(bào)文斷開
    發(fā)表于 10-14 14:01

    CC2540應(yīng)用層的接受數(shù)據(jù)的buffer在哪

    CC2540應(yīng)用層的接受數(shù)據(jù)的buffer在哪,因?yàn)椋蚁胪鈹U(kuò)CPU,需要做個(gè)透明傳輸。還望指點(diǎn)主從設(shè)備接受發(fā)送buffer分別在源程序哪里
    發(fā)表于 02-23 10:00

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

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

    【學(xué)習(xí)打卡】OpenHarmony的應(yīng)用層說明

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

    CH582如何強(qiáng)制發(fā)送廣播?

    RT,原來使用PHY直接發(fā),現(xiàn)在功能升級(jí),使用了外設(shè)模式。通過廣播發(fā)送狀態(tài),當(dāng)狀態(tài)改變的時(shí)候如何強(qiáng)制發(fā)送?不然廣播間隔較長,要等到下次廣播。還有能否動(dòng)態(tài)修改廣播長度?如
    發(fā)表于 08-01 07:52

    LWIP TCP報(bào)文基礎(chǔ)知識(shí)及其LWIP中TCP協(xié)議的實(shí)現(xiàn)

    接收完成后才將數(shù)據(jù)遞交到應(yīng)用層。2 TCP 報(bào)文段結(jié)構(gòu)TCP 報(bào)文段依賴 IP 協(xié)議進(jìn)行發(fā)送,因此 TCP
    發(fā)表于 10-18 14:54

    tcp連接斷開連接圖解

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

    關(guān)于tcp協(xié)議棧中rst報(bào)文的seq跳變問題

    導(dǎo)致內(nèi)核協(xié)議棧發(fā)送了一個(gè)rst報(bào)文,而rst報(bào)文選取seq的時(shí)候,并不是選取的確定已經(jīng)發(fā)送的se
    的頭像 發(fā)表于 07-27 15:26 ?5057次閱讀
    關(guān)于tcp協(xié)議棧中<b class='flag-5'>rst</b><b class='flag-5'>報(bào)文</b>的seq跳變問題

    如何解釋TCP報(bào)文的內(nèi)容

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

    為什么系統(tǒng)會(huì)自動(dòng)回復(fù)RST報(bào)文

    從結(jié)果中可以看到 10.223.12.10 在接收到對(duì)端回應(yīng)的 syn + ack 后,系統(tǒng)會(huì)自動(dòng)給對(duì)端回應(yīng)一個(gè) RST 復(fù)位報(bào)文,導(dǎo)致二者的鏈路斷開
    的頭像 發(fā)表于 11-16 17:19 ?2046次閱讀

    應(yīng)用層知多少?(總結(jié)在末尾)

    的語法、語義;進(jìn)程何時(shí)、如何發(fā)送報(bào)?,以及對(duì)報(bào)?進(jìn)?響應(yīng)的規(guī)則。應(yīng)用層功能與協(xié)議:域名服務(wù):DNS;?件傳輸:FTP;電?郵件:SMTP、POP3;遠(yuǎn)程登陸:TE
    的頭像 發(fā)表于 08-26 11:16 ?1395次閱讀
    <b class='flag-5'>應(yīng)用層</b>知多少?(總結(jié)在末尾)

    物聯(lián)網(wǎng)的技術(shù)架構(gòu)及應(yīng)用層是什么?

    物聯(lián)網(wǎng)的技術(shù)架構(gòu)包括感知、網(wǎng)絡(luò)、平臺(tái)應(yīng)用層應(yīng)用層是物聯(lián)網(wǎng)的頂層,它的主要功能是將感知
    的頭像 發(fā)表于 07-15 08:56 ?3771次閱讀

    基于TCP應(yīng)用層協(xié)議

    ; 我們把攜帶RST標(biāo)識(shí)的稱為復(fù)位報(bào)文段 SYN: 請(qǐng)求建立連接; 我們把攜帶SYN標(biāo)識(shí)的稱為同步報(bào)文段 FIN: 通知對(duì)方, 本端要關(guān)閉了, 我們稱攜
    的頭像 發(fā)表于 11-11 11:23 ?969次閱讀
    基于TCP<b class='flag-5'>應(yīng)用層</b>協(xié)議

    CAN報(bào)文為什么會(huì)發(fā)送失敗?

    CAN總線調(diào)試過程中出現(xiàn)報(bào)文發(fā)送失敗。很多工程師都對(duì)此只知其一不知其二,今天我們就以CAN報(bào)文發(fā)送失敗的問題來做一次探討。在了解CAN報(bào)文
    的頭像 發(fā)表于 04-12 08:25 ?2168次閱讀
    CAN<b class='flag-5'>報(bào)文</b>為什么會(huì)<b class='flag-5'>發(fā)送</b>失敗?
    主站蜘蛛池模板: zoovideo人与驴mp4| 3D动漫网站HOXXXxes| 久久国产精品麻豆AV影视| 国产成人免费a在线视频app| 91久久偷偷做嫩草影院免| 伊人久久大香线蕉观看| 亚洲欧美中文字幕高清在线| 日本久久免费大片| 欧美亚洲另类热图| 免费看a毛片| 美女扒开尿口直播| 免费黄色网址在线观看| 欧美自拍亚洲综合图区| 色婷婷99综合久久久精品| 人妻激情综合久久久久蜜桃| 欧美双拳极限扩张| 美美哒免费影视8| 日本孕妇大胆孕交| 性刺激欧美三级在线现看中文| 我的好妈妈8高清在线观看WWW| 四虎永久在线精品免费A| 日韩欧美三区| 日韩人妻无码精品-专区| 无止侵犯高H1V3无止侵犯| 无码AV毛片色欲欧洲美洲| 亚洲区偷拍自拍29P| 97超视频在线观看| 俄罗斯少女人体| 国产精品青青草原app大全| 国产精品永久在线| 国产视频成人| 回复术士人生重启在线观看| 韩日午夜在线资源一区二区| 黑人猛挺进小莹的体内视频| 美女胸被男子强捏视频| 欧美特级特黄a大片免费| 无人区乱码1区2区3区网站| 中文字幕在线观看| yy8090韩国理伦片在线| 国内久久久久影院精品| 就去色电影|