www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 嵌入式 > 嵌入式軟件
[導(dǎo)讀] 環(huán)境:Client 通過(guò)tcp 連接server,server端只是listen,但是不調(diào)用accept。通過(guò)netstat –ant查看兩端的連接情況。server端listen,不調(diào)用accept。client一直去con

 環(huán)境:

Client 通過(guò)tcp 連接server,server端只是listen,但是不調(diào)用accept。通過(guò)netstat –ant查看兩端的連接情況。

server端listen,不調(diào)用accept。

client一直去connect server。

問(wèn)題:

運(yùn)行一段時(shí)間后,為什么server端的ESTABLISHED連接的個(gè)數(shù)基本是固定的129個(gè),但是client端的ESTABLISHED連接的個(gè)數(shù)卻在不斷增加?

分析

Linux內(nèi)核協(xié)議棧為一個(gè)tcp連接管理使用兩個(gè)隊(duì)列,一個(gè)是半鏈接隊(duì)列(用來(lái)保存處于SYN_SENT和SYN_RECV狀態(tài)的請(qǐng)求),一個(gè)是accpetd隊(duì)列(用來(lái)保存處于established狀態(tài),但是應(yīng)用層沒(méi)有調(diào)用accept取走的請(qǐng)求)。

第一個(gè)隊(duì)列的長(zhǎng)度是/proc/sys/net/ipv4/tcp_max_syn_backlog,默認(rèn)是1024。如果開(kāi)啟了syncookies,那么基本上沒(méi)有限制。

第二個(gè)隊(duì)列的長(zhǎng)度是/proc/sys/net/core/somaxconn,默認(rèn)是128,表示最多有129個(gè)established鏈接等待accept。(為什么是129?詳見(jiàn)下面的附錄1)。

現(xiàn)在假設(shè)acceptd隊(duì)列已經(jīng)達(dá)到129的情況:

client發(fā)送syn到server。client(SYN_SENT),server(SYN_RECV)

server端處理流程:tcp_v4_do_rcv--->tcp_rcv_state_process--->tcp_v4_conn_request

if(sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_yong(sk)>1)

goto drop;

inet_csk_reqsk_queue_yong(sk)的含義是請(qǐng)求隊(duì)列中有多少個(gè)握手過(guò)程中沒(méi)有重傳過(guò)的段。

在第一次的時(shí)候,之前的握手過(guò)程都沒(méi)有重傳過(guò),所以這個(gè)syn包server端會(huì)直接drop掉,之后client會(huì)重傳syn,當(dāng)inet_csk_reqsk_queue_yong(sk) < 1,那么這個(gè)syn被server端接受。server會(huì)回復(fù)synack給client。這樣一來(lái)兩邊的狀態(tài)就變?yōu)閏lient(ESTABLISHED), server(SYN_SENT)

Client收到synack后回復(fù)ack給server。

server端處理流程: tcp_check_req--->syn_recv_sock-->tcp_v4_syn_recv_sock

if(sk_acceptq_is_full(sk)

goto exit_overflow;

如果server端設(shè)置了sysctl_tcp_abort_on_overflow,那么server會(huì)發(fā)送rst給client,并刪除掉這個(gè)鏈接;否則server端只是記錄一下LINUX_MIB_LISTENOVERFLOWS(詳見(jiàn)附錄2),然后返回。默認(rèn)情況下是不會(huì)設(shè)置的,server端只是標(biāo)記連接請(qǐng)求塊的acked標(biāo)志,之后連接建立定時(shí)器,會(huì)遍歷半連接表,重新發(fā)送synack,重復(fù)上面的過(guò)程(具體的函數(shù)是inet_csk_reqsk_queue_prune),如果重傳次數(shù)超過(guò)synack重傳的閥值(/proc/sys/net/ipv4/tcp_synack_retries),會(huì)把該連接從半連接鏈表中刪除。

一次異常問(wèn)題分析

Nginx通過(guò)FASTCGI協(xié)議連接cgi程序,出現(xiàn)cgi程序read讀取socket內(nèi)容的時(shí)候永遠(yuǎn)block。通過(guò)netstat查看,cgi程序所在的服務(wù)器上顯示連接存在,但是nginx所在的服務(wù)器上顯示不存在該連接。

下面是原始數(shù)據(jù)圖:

我們從上面的數(shù)據(jù)流來(lái)分析一下:

出現(xiàn)問(wèn)題的時(shí)候,cgi程序(tcp server端)處理非常慢,導(dǎo)致大量的連接請(qǐng)求放到accept隊(duì)列,把a(bǔ)ccept隊(duì)列阻塞。

148021 nginx(tcp client端) 連接cgi程序,發(fā)送syn

此時(shí)server端accpet隊(duì)列已滿,并且inet_csk_reqsk_queue_yong(sk) > 1,server端直接丟棄該數(shù)據(jù)包

148840 client端等待3秒后,重傳SYN

此時(shí)server端狀態(tài)與之前送變化,仍然丟棄該數(shù)據(jù)包

150163 client端又等待6秒后,重傳SYN

此時(shí)server端accept隊(duì)列仍然是滿的,但是存在了重傳握手的連接請(qǐng)求,server端接受連接請(qǐng)求,并發(fā)送synack給client端(150164)

150166 client端收到synack,標(biāo)記本地連接為ESTABLISHED狀態(tài),給server端應(yīng)答ack,connect系統(tǒng)調(diào)用完成。

Server收到ack后,嘗試將連接放到accept隊(duì)列,但是因?yàn)閍ccept隊(duì)列已滿,所以只是標(biāo)記連接為acked,并不會(huì)將連接移動(dòng)到accept隊(duì)列中,也不會(huì)為連接分配sendbuf和recvbuf等資源。

150167 client端的應(yīng)用程序,檢測(cè)到connect系統(tǒng)調(diào)用完成,開(kāi)始向該連接發(fā)送數(shù)據(jù)。

Server端收到數(shù)據(jù)包,由于acept隊(duì)列仍然是滿的,所以server端處理也只是標(biāo)記acked,然后返回。

150225 client端由于沒(méi)有收到剛才發(fā)送數(shù)據(jù)的ack,所以會(huì)重傳剛才的數(shù)據(jù)包

150296 同上

150496 同上

150920 同上

151112 server端連接建立定時(shí)器生效,遍歷半連接鏈表,發(fā)現(xiàn)剛才acked的連接,重新發(fā)送synack給client端。

151113 client端收到synack后,根據(jù)ack值,使用SACK算法,只重傳最后一個(gè)ack內(nèi)容。

Server端收到數(shù)據(jù)包,由于accept隊(duì)列仍然是滿的,所以server端處理也只是標(biāo)記acked,然后返回。

151896 client端等待3秒后,沒(méi)有收到對(duì)應(yīng)的ack,認(rèn)為之前的數(shù)據(jù)包也丟失,所以重傳之前的內(nèi)容數(shù)據(jù)包。

152579 server端連接建立定時(shí)器生效,遍歷半連接鏈表,發(fā)現(xiàn)剛才acked的連接,synack重傳次數(shù)在閥值以內(nèi),重新發(fā)送synack給client端。

152581 cient端收到synack后,根據(jù)ack值,使用SACK算法,只重傳最后一個(gè)ack內(nèi)容。

Server端收到數(shù)據(jù)包,由于accept隊(duì)列仍然是滿的,所以server端處理也只是標(biāo)記acked,然后返回

153455 client端等待3秒后,沒(méi)有收到對(duì)應(yīng)的ack,認(rèn)為之前的數(shù)據(jù)包也丟失,所以重傳之前的內(nèi)容數(shù)據(jù)包。

155399 server端連接建立定時(shí)器生效,遍歷半連接鏈表,發(fā)現(xiàn)剛才acked的連接,synack重傳次數(shù)在閥值以內(nèi),重新發(fā)送synack給client端。

155400 cient端收到synack后,根據(jù)ack值,使用SACK算法,只重傳最后一個(gè)ack內(nèi)容。

Server端收到數(shù)據(jù)包,由于accept隊(duì)列仍然是滿的,所以server端處理也只是標(biāo)記acked,然后返回。

156468 client端等待幾秒后,沒(méi)有收到對(duì)應(yīng)的ack,認(rèn)為之前的數(shù)據(jù)包也丟失,所以重傳之前的內(nèi)容數(shù)據(jù)包。

161309 server端連接建立定時(shí)器生效,遍歷半連接鏈表,發(fā)現(xiàn)剛才acked的連接,synack重傳次數(shù)在閥值以內(nèi),重新發(fā)送synack給client端。[!--empirenews.page--]

161310 cient端收到synack后,根據(jù)ack值,使用SACK算法,只重傳最后一個(gè)ack內(nèi)容。

Server端收到數(shù)據(jù)包,由于accept隊(duì)列仍然是滿的,所以server端處理也只是標(biāo)記acked,然后返回。

162884 client端等待幾秒后,沒(méi)有收到對(duì)應(yīng)的ack,認(rèn)為之前的數(shù)據(jù)包也丟失,所以重傳之前的內(nèi)容數(shù)據(jù)包。

Server端收到數(shù)據(jù)包,由于accept隊(duì)列仍然是滿的,所以server端處理也只是標(biāo)記acked,然后返回。

164828 client端等待一段時(shí)間后,認(rèn)為連接不可用,于是發(fā)送FIN、ACK給server端。Client端的狀態(tài)變?yōu)镕IN_WAIT1,等待一段時(shí)間后,client端將看不到該鏈接。

164829 server端收到ACK后,此時(shí)cgi程序處理完一個(gè)請(qǐng)求,從accept隊(duì)列中取走一個(gè)連接,此時(shí)accept隊(duì)列中有了空閑,server端將請(qǐng)求的連接放到accept隊(duì)列中。

這樣cgi所在的服務(wù)器上顯示該鏈接是established的,但是nginx(client端)所在的服務(wù)器上已經(jīng)沒(méi)有該鏈接了。

之后,當(dāng)cgi程序從accept隊(duì)列中取到該連接后,調(diào)用read去讀取sock中的內(nèi)容,但是由于client端早就退出了,所以read就會(huì)block那里了。

問(wèn)題解決

或許你會(huì)認(rèn)為在164829中,server端不應(yīng)該建立連接,這是內(nèi)核的bug。但是內(nèi)核是按照RFC來(lái)實(shí)現(xiàn)的,在3次握手的過(guò)程中,是不會(huì)判斷FIN標(biāo)志位的,只會(huì)處理SYN、ACK、RST這三種標(biāo)志位。

從應(yīng)用層的角度來(lái)考慮解決問(wèn)題的方法,那就是使用非阻塞的方式read,或者使用select超時(shí)方式read;亦或者nginx中關(guān)閉連接的時(shí)候使用RST方式,而不是FIN方式。

附錄1

when I use linux TCP socket, and find there is a bug in function sk_acceptq_is_full():

When a new SYN comes, TCP module first checks its validation. If valid,send SYN,ACK to the client and add the sock

to the syn hash table.

Next time if received the valid ACK for SYN,ACK from the client. server will accept this connection and increase the

sk->sk_ack_backlog -- which is done in function tcp_check_req().

We check wether acceptq is full in function tcp_v4_syn_recv_sock().

Consider an example:

After listen(sockfd, 1) system call, sk->sk_max_ack_backlog is set to

As we know, sk->sk_ack_backlog is initialized to 0. Assuming accept() system call is not invoked now

1. 1st connection comes. invoke sk_acceptq_is_full(). sk->sk_ack_backlog=0 sk->sk_max_ack_backlog=1, function return 0 accept this connection. Increase the sk->sk_ack_backlog

2. 2nd connection comes. invoke sk_acceptq_is_full(). sk->sk_ack_backlog=1 sk->sk_max_ack_backlog=1, function return 0 accept this connection. Increase the sk->sk_ack_backlog

3. 3rd connection comes. invoke sk_acceptq_is_full(). sk->sk_ack_backlog=2 sk->sk_max_ack_backlog=1, function return 1. Refuse this connection.I think it has bugs. after listen system call. sk->sk_max_ack_backlog=1

but now it can accept 2 connections.

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

上海2025年9月5日 /美通社/ -- 由紐倫堡會(huì)展(上海)有限公司舉辦的上海國(guó)際嵌入式會(huì)議將于 2025 年 10 月 16-17 日在上海世博展覽館舉辦。 此次會(huì)議將由三個(gè)版塊組成:嵌入式技術(shù)會(huì)議、汽...

關(guān)鍵字: 嵌入式 CE CHINA EMBEDDED

-DXC通過(guò)初創(chuàng)企業(yè)合作推動(dòng)汽車與制造業(yè)AI創(chuàng)新 初創(chuàng)企業(yè)Acumino、CAMB.AI與GreenMatterAI合作將AI創(chuàng)新推向市場(chǎng) 合作源于DXC與STARTUP AUTOBAHN的伙伴關(guān)系 弗吉尼亞州阿什...

關(guān)鍵字: 汽車 AI AN AC

CPU親和度通過(guò)限制進(jìn)程或線程可以運(yùn)行的CPU核心集合,使得它們只能在指定的CPU核心上執(zhí)行。這可以減少CPU緩存的失效次數(shù),提高緩存命中率,從而提升系統(tǒng)性能。

關(guān)鍵字: Linux 嵌入式

在Linux系統(tǒng)性能優(yōu)化中,內(nèi)存管理與網(wǎng)絡(luò)連接處理是兩大核心領(lǐng)域。vm.swappiness與net.core.somaxconn作為關(guān)鍵內(nèi)核參數(shù),直接影響系統(tǒng)在高負(fù)載場(chǎng)景下的穩(wěn)定性與響應(yīng)速度。本文通過(guò)實(shí)戰(zhàn)案例解析這兩個(gè)...

關(guān)鍵字: Linux 內(nèi)存管理

臺(tái)北2025年8月8日 /美通社/ -- 作為專業(yè)伺服器設(shè)計(jì)與制造商,神達(dá)控股股份有限公司(股票代號(hào):3706)旗下子公司神雲(yún)科技股份有限公司(MiTAC Computing Technology Corporation...

關(guān)鍵字: MIT AI AC BSP

多款高性能平臺(tái)登場(chǎng),以快速響應(yīng)服務(wù)能力滿足中國(guó)多元化市場(chǎng)需求 上海2025年7月26日 /美通社/ -- 世界人工智能大會(huì)訊—神雲(yún)科技股份有限公司(MiTAC Computing Technology Cor...

關(guān)鍵字: AI 數(shù)據(jù)中心 IC AC

對(duì)于LLM,我使用b谷歌Gemini的免費(fèi)層,所以唯一的成本是n8n托管。在使用了n8n Cloud的免費(fèi)積分后,我決定將其托管在Railway上(5美元/月)。然而,由于n8n是開(kāi)源的,您可以在自己的服務(wù)器上托管它,而...

關(guān)鍵字: 人工智能 n8n Linux

在Linux系統(tǒng)管理中,權(quán)限控制是安全運(yùn)維的核心。本文通過(guò)解析/etc/sudoers文件配置與組策略的深度應(yīng)用,結(jié)合某金融企業(yè)生產(chǎn)環(huán)境案例(成功攔截98.7%的非法提權(quán)嘗試),揭示精細(xì)化權(quán)限管理的關(guān)鍵技術(shù)點(diǎn),包括命令別...

關(guān)鍵字: Linux 用戶權(quán)限 sudoers文件

Linux內(nèi)核中的信號(hào)量(Semaphore)是一種用于資源管理的同步原語(yǔ),它允許多個(gè)進(jìn)程或線程對(duì)共享資源進(jìn)行訪問(wèn)控制。信號(hào)量的主要作用是限制對(duì)共享資源的并發(fā)訪問(wèn)數(shù)量,從而防止系統(tǒng)過(guò)載和數(shù)據(jù)不一致的問(wèn)題。

關(guān)鍵字: Linux 嵌入式

在云計(jì)算與容器化技術(shù)蓬勃發(fā)展的今天,Linux網(wǎng)絡(luò)命名空間(Network Namespace)已成為構(gòu)建輕量級(jí)虛擬網(wǎng)絡(luò)的核心組件。某頭部互聯(lián)網(wǎng)企業(yè)通過(guò)命名空間技術(shù)將測(cè)試環(huán)境資源消耗降低75%,故障隔離效率提升90%。本...

關(guān)鍵字: Linux 云計(jì)算
關(guān)閉