新聞中心
隨著互聯(lián)網(wǎng)技術(shù)的不斷發(fā)展,網(wǎng)絡(luò)通信在人們的日常生活中扮演著至關(guān)重要的角色。在現(xiàn)代化的網(wǎng)絡(luò)通信中,長連接一直是一種非常常見的通信方式。Linux作為一個開源的操作系統(tǒng),其提供的長連接也一直備受人們青睞。本文將詳細(xì)介紹Linux長連接的概念、原理、優(yōu)點和應(yīng)用,并對幾個常見的長連接實現(xiàn)進行了詳細(xì)分析。

成都網(wǎng)站設(shè)計、做網(wǎng)站、成都外貿(mào)網(wǎng)站建設(shè)公司服務(wù)團隊是一支充滿著熱情的團隊,執(zhí)著、敏銳、追求更好,是創(chuàng)新互聯(lián)的標(biāo)準(zhǔn)與要求,同時竭誠為客戶提供服務(wù)是我們的理念。創(chuàng)新互聯(lián)建站把每個網(wǎng)站當(dāng)做一個產(chǎn)品來開發(fā),精雕細(xì)琢,追求一名工匠心中的細(xì)致,我們更用心!
一、Linux長連接的概念
Linux長連接是指在一個TCP連接上保持連續(xù)不斷的信息傳輸,直到通信結(jié)束或有特別的指示。相對于短連接,長連接在進行網(wǎng)絡(luò)通信時,不需要頻繁地建立和關(guān)閉連接,從而節(jié)省了資源和時間。在Linux中,長連接通常通過socket實現(xiàn),可以實現(xiàn)可靠的數(shù)據(jù)傳輸。
二、Linux長連接的原理
長連接的實現(xiàn)原理是在TCP連接應(yīng)用層與傳輸層之間增加一個心跳機制。當(dāng)有數(shù)據(jù)需要發(fā)送時,先發(fā)送心跳包,告訴對方連接還在,然后再發(fā)送數(shù)據(jù)。如果在一段時間內(nèi)沒有數(shù)據(jù)發(fā)送,就會發(fā)送一個更長時間的心跳包,保持連接的有效性。這樣就可以避免服務(wù)端在一些可能很短暫的空閑時間內(nèi)關(guān)閉連接,以避免資源浪費。
三、Linux長連接的優(yōu)點
1.穩(wěn)定性
長連接提供了更穩(wěn)定的通信方式,不需要頻繁地建立和關(guān)閉連接。相對于短連接,長連接更不容易出現(xiàn)網(wǎng)絡(luò)中斷和斷線等問題。
2.效率
長連接可以實現(xiàn)數(shù)據(jù)在TCP連接上連續(xù)不斷地傳輸,減少了因建立和關(guān)閉連接引起的成本,同時也減少了網(wǎng)絡(luò)帶寬的消耗。在高并發(fā)和高負(fù)載的情況下,使用長連接可以提高通信效率。
3.靈活性
長連接還可以通過控制心跳包的發(fā)送時間調(diào)整連接的靈活性。根據(jù)具體應(yīng)用場景,可以靈活地調(diào)整心跳包的發(fā)送間隔,以更好地適應(yīng)網(wǎng)絡(luò)環(huán)境。
四、Linux長連接的應(yīng)用
1.聊天應(yīng)用
在聊天應(yīng)用中,長連接可以實現(xiàn)即時通信的功能。當(dāng)用戶發(fā)送一條消息時,可以通過長連接讓服務(wù)器實時地將消息推送給對方。使用長連接,可以避免用戶頻繁請求服務(wù)器,實現(xiàn)更優(yōu)秀的體驗。
2.直播應(yīng)用
在直播應(yīng)用中,長連接可以實現(xiàn)實時的直播彈幕和在線人數(shù)等功能。當(dāng)用戶觀看一場直播時,可以通過長連接實時地推送彈幕和當(dāng)前在線人數(shù)等信息。
3.物聯(lián)網(wǎng)應(yīng)用
在物聯(lián)網(wǎng)應(yīng)用中,長連接可以實現(xiàn)設(shè)備之間的實時通信。當(dāng)一個設(shè)備的狀態(tài)發(fā)生變化時,可以通過長連接實時地將數(shù)據(jù)推送到監(jiān)控設(shè)備或其他相關(guān)設(shè)備。
五、常見的Linux長連接實現(xiàn)
1. Nginx
Nginx是一個高性能的Web服務(wù)器,其也支持長連接技術(shù)。通過Nginx提供的keepalive模塊,可以實現(xiàn)高效的長連接應(yīng)用。
2. WebSocket
WebSocket是一種基于HTTP的協(xié)議,可以實現(xiàn)瀏覽器和服務(wù)器之間的雙向通信。通過WebSocket,可以輕松實現(xiàn)長連接技術(shù),其使用長連接進行通信。
3. Redis
Redis是一個支持緩存、消息隊列、發(fā)布訂閱等功能的存儲系統(tǒng)。在Redis中,也可以實現(xiàn)長連接技術(shù),并通過發(fā)布訂閱機制實現(xiàn)實時通信。
Linux長連接是一種穩(wěn)定高效的網(wǎng)絡(luò)通信方式,其在現(xiàn)代網(wǎng)絡(luò)通信中扮演著非常重要的角色。通過充分理解Linux長連接的概念、原理、優(yōu)點和應(yīng)用,可以實現(xiàn)更高效、靈活、穩(wěn)定的網(wǎng)絡(luò)通信。
成都網(wǎng)站建設(shè)公司-創(chuàng)新互聯(lián),建站經(jīng)驗豐富以策略為先導(dǎo)10多年以來專注數(shù)字化網(wǎng)站建設(shè),提供企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計,響應(yīng)式網(wǎng)站制作,設(shè)計師量身打造品牌風(fēng)格,熱線:028-86922220基于事件驅(qū)動的高性能開源網(wǎng)絡(luò)庫libevent介紹及安裝
libevent是一個輕量級的基于事件驅(qū)動的高性能的開源網(wǎng)絡(luò)庫,并且支持多個平臺,對多個平臺的I/O復(fù)用技術(shù)進行了封裝,當(dāng)我們編譯庫的代碼時,編譯的腳本將會根據(jù)OS支持的處理事件機制,來編譯相應(yīng)的代碼,從而在libevent接口上保持一致。
在當(dāng)前的服務(wù)器上,面對的主要問題就是要能處理大量的連接。而通過libevent這個網(wǎng)絡(luò)庫,我們就可以調(diào)用它的API來很好的解決上面的問題。首先,可以來回顧一下,對這個問題的傳統(tǒng)解決方法。
問題:
如何處理多個客戶端連接
解決方案1:
I/O復(fù)用技術(shù)
這幾種方式都是同步I/O,即當(dāng)讀寫事件就緒,他們自己需要負(fù)責(zé)進行讀寫,這個讀寫過程是阻塞的,而異步I/O則不需要自己負(fù)責(zé)讀寫,只需要通知負(fù)責(zé)讀寫的程序就可以了。
解決方案2:
多線程技術(shù)或多進程技術(shù)
多線程技術(shù)和多進程技術(shù)也可以處理高并發(fā)的數(shù)據(jù)連接,因為在服務(wù)器中可以產(chǎn)生大量的進程和線程和處理我們需要監(jiān)視的連接。但是,這兩種方式也是有很大的局限性的,比如多進程模型就不適合大量的短連接,因為進程的產(chǎn)生和關(guān)閉需要消耗較大的系統(tǒng)性能,同樣,還要進程進程間的通信,在CPU性能不足的情況下不太適合。而多線程技術(shù)則不太適合處理長連接,因為當(dāng)我們建立一個進程時,linux中會消耗8G的??臻g,如果我們的每個連接都杵著不斷開,那么大量連接長連接后,導(dǎo)致的結(jié)果就是內(nèi)存的大量消耗。
解決方案3:
常用的上述二者復(fù)合使用
上述的兩種方法各具有優(yōu)缺點,因此,我們可以將上述的方法結(jié)合起來,這也是目前使用較多的處理高并發(fā)的方法。多進程+I/O復(fù)用或者多線程+I/O復(fù)用。而在具體的實現(xiàn)上,又可以分為很多的方式。比如多線程+I/O復(fù)用技術(shù),我們使春旁轎用使用一個主線程負(fù)責(zé)監(jiān)聽一個端口和接受的描述符是否有讀寫事件產(chǎn)生,如果有,則將事件分發(fā)給其他的工作進程去完啟吵成,這也是進程池的理念。
在說完上述的高并發(fā)的處理方法之后,我們可以來介紹一個libevent的主要特色了。
同樣,lievent也是采用的上述系統(tǒng)提供的select,poll和epoll方法來進行I/O復(fù)用,但是針對于多個系統(tǒng)平臺上的不同的I/O復(fù)用實現(xiàn)方式,libevent進行了重新的封裝,并提供了統(tǒng)一的API接口。libevent在實現(xiàn)上使用了事件驅(qū)動這種機制,其本質(zhì)上是一種Reactor模式。
在Libevent中也是一樣,向Libevent框架注冊相應(yīng)的事件和回調(diào)函數(shù);當(dāng)這些事件發(fā)生時,Libevent會調(diào)用這些回調(diào)函數(shù)處理相應(yīng)的事件。
lbevent的事件支持三種,分別是網(wǎng)絡(luò)IO、定時器和信號。定時器的數(shù)據(jù)結(jié)構(gòu)使用最小堆(Min Heap),以提高效率。網(wǎng)絡(luò)IO和信號的數(shù)據(jù)結(jié)構(gòu)采用了雙向鏈表(TAILQ)。
更多l(xiāng)inux內(nèi)核視頻教程文本資料免費獲取后臺私信【內(nèi)核】。
libevent的安裝很簡單,我是直接從github上clone下一個源碼,然后進行編譯安裝的。
具體的命令是(假設(shè)扒肆你已經(jīng)安裝了git):
現(xiàn)在的libevent版本已經(jīng)到達libevent2了,其增加了多線程的支持,API函數(shù)也發(fā)生了一些微小的變化。
如果你想知道更多的API使用情況,請點擊這里。
下面,就基于libevent2編寫一個聊天室服務(wù)器。
設(shè)計思想:
首先創(chuàng)建一個套接字,進而創(chuàng)建一個事件對此端口進行監(jiān)聽,將所請求的用戶組成一個隊列,并監(jiān)聽所有的用戶事件,當(dāng)某個用戶說話了,產(chǎn)生了讀事件,就將該用戶的發(fā)言發(fā)送給隊列中的其他用戶。
程序分析
需要包含的libevent函數(shù)頭:
創(chuàng)建一個client結(jié)構(gòu)體,接受連接后存放數(shù)據(jù):
先來看下mian函數(shù)的處理:
首先,函數(shù)初始化了一個用戶隊列tailq,接著創(chuàng)建了一個socket套接字,并將套接字設(shè)定為非阻塞模式,接著對一個全局的evbase事件,注冊了事件,事件源是listen_fd,回調(diào)函數(shù)是on_accept,事件發(fā)生的情況是EV_READ,而且標(biāo)志EV_PESIST表明該事件一直存在,而后開啟事件掃描循環(huán)event_base_dispatch(evbase)。
再看一下回調(diào)函數(shù)on_accpet實現(xiàn):
這個回調(diào)函數(shù)的作用很顯然,就是接受了一個客戶端的請求,并申請好了一個client信息,將需要的內(nèi)容填寫好,在填寫中需要注意的是,又向上述的事件集evbase中注冊了一個bufferevent事件client->buf_ev,并注冊了回調(diào)函數(shù)buffered_on_read,buffered_on_error,這三個函數(shù)分別是當(dāng)接受后的連接發(fā)生了讀或者錯誤事件后的執(zhí)行函數(shù)。接著,將用戶的client結(jié)構(gòu)放入了用戶的隊列tailq中去。
用戶的buffer可讀后的執(zhí)行函數(shù):
執(zhí)行函數(shù)的作用很明顯,將libevent管理中的buffer數(shù)據(jù)讀取出,存入本地的data數(shù)組內(nèi),然后對隊列中的client進行檢索,如果不是發(fā)數(shù)據(jù)的client,則將數(shù)據(jù)寫入該client的buffer中,發(fā)送給該用戶。這里注意的是需要反復(fù)讀取buffer中的數(shù)據(jù),防止一個讀取并沒有讀取干凈,直到讀取不到數(shù)據(jù)為止。
buffer出錯處理函數(shù)和上述函數(shù)差不多,功能就是出錯后,結(jié)束掉保存的client結(jié)構(gòu),詳細(xì)就不說了。
編譯的時候記得修改Makefile中Libevent文件夾的位置
設(shè)計思想:
所謂回顯服務(wù)器就是將客戶端發(fā)過來的數(shù)據(jù)再發(fā)回去,這里主要也就是說明libevent的純IO復(fù)用實現(xiàn)。實現(xiàn)方法和上面的差不多,甚至可以說更加簡單。
程序和上面的聊天服務(wù)器差不多,只是在buffer可讀的事件函數(shù)中,不是將用戶的數(shù)據(jù)發(fā)送給其他用戶,而是直接發(fā)送給用戶本身。
設(shè)計思想:
上面的方法單純使用libevent的簡單函數(shù)來實現(xiàn)服務(wù),但是這里,我們假設(shè)我們需要處理的客戶端很少,于是我們可以使用對于每個連接我們分配一個線程這樣的方式來實現(xiàn)對用戶的服務(wù)。這種方式簡單有效,一對一服務(wù),就算業(yè)務(wù)邏輯出現(xiàn)阻塞也不怕。
程序分析
首先定義了一些數(shù)據(jù)結(jié)構(gòu),worker數(shù)據(jù)結(jié)構(gòu)定義的是一個工作者,它包含有一個工作線程,和結(jié)束標(biāo)志,需要獲取的工作隊列,和建立鏈表需要的指針。job數(shù)據(jù)結(jié)構(gòu)定義的是操作一個job的方法和對象,這回到程序中,實際上就是指的是事件發(fā)生后,封裝好的client結(jié)構(gòu)體和處理這個結(jié)構(gòu)體的方法。workqueue數(shù)據(jù)結(jié)構(gòu)指的是當(dāng)前的工作隊列中的工作者,以及工作隊列中的待完成的工作,以及互斥鎖和條件變量(因為多個工作進程需要訪問這些資源)。
具體的流程就是,用一個主線程監(jiān)聽一個套接字,并將套接字接受到的連接accept,并創(chuàng)建一個client數(shù)據(jù)結(jié)構(gòu)保存該連接的信息,在這個client結(jié)構(gòu)中注冊一個bufferevent事件,注冊到client->evbase上(這時候這是向client中的evbase注冊了一個事件還沒有進行循環(huán)這個事件集)。
接著,當(dāng)監(jiān)聽到某個client有bufferevent事件發(fā)生,主線程就把該client結(jié)構(gòu)體和需要進行的工作方法包裝成一個job結(jié)構(gòu),然后把這個job扔到workqueue上去,并通知各個工作者。而后,各個工作者開著的線程就被激活了,瘋狂地去workqueue上去搶工作做,某個worker拿到工作后,就可以解包job,根據(jù)job的工作說明書(job_function)操作工作對象(client)了。這里,job的工作說明有是循環(huán)client中的client->evbase,于是這樣線程就會一直去監(jiān)視這個連接的狀態(tài),如果有數(shù)據(jù)就這會調(diào)用回調(diào)函數(shù)進行處理。同時,這個線程也就是阻塞在這里,這對這一個連接負(fù)責(zé)。
建立workqueue需要的結(jié)構(gòu)體和函數(shù)有:
主線程的on_accept函數(shù)為:
job中的工作指南為:
設(shè)計思想:
假設(shè)我們的用戶很多,高并發(fā),長連接,那么我們還是來用I/O復(fù)用和線程池實現(xiàn)吧,用一個控制線程通過I/O復(fù)用負(fù)責(zé)監(jiān)聽和分發(fā)事件,用一組線程池來進行處理事件,這樣就可以靈活地將控制邏輯和業(yè)務(wù)邏輯分開了,見下述講解。
程序分析
具體的流程和上面的差不多,用一個主線程監(jiān)聽一個套接字,并將套接字接受到的連接accept,并創(chuàng)建一個client數(shù)據(jù)結(jié)構(gòu)保存該連接的信息,在這個client結(jié)構(gòu)中注冊一個bufferevent事件,但是這里,將事件注冊到accept_evbase中,仍然用主線程進行監(jiān)聽。
而面對監(jiān)聽后出現(xiàn)的事件,將client和操作client的方法打包成一個job,放到上述的workqueue中去,讓工作進程來完成。這樣的操作和上述的差別在于上述方法將bufferevent注冊到client中的evbase中,用工作線程監(jiān)聽,而本方法用主線程監(jiān)聽,工作線程負(fù)責(zé)處理監(jiān)聽產(chǎn)生的事件。
這要的差別在于兩個函數(shù) on_accept函數(shù):
在buffered_on_read中,提交job。
在job工作指南server_job_function中就可以做你工作該做的事兒了,根據(jù)發(fā)來的信息進行數(shù)據(jù)庫處理,http返回等等。
暢談linux下TCP(上)
tcp 協(xié)議 是互聯(lián)網(wǎng)中最常用的協(xié)議 , 開發(fā)人員基本上天天和它打交道,對它進行深入了解。 可以幫助我們排查定位bug和進行程序優(yōu)化。下面我將就TCP幾個點做深入的探討
客戶端:收到 ack 后 分配連接資源。 發(fā)送數(shù)據(jù)
服務(wù)器 : 收到 syn 后立即 分配連接資源
客戶端:收到ACK, 立即分配資源
服務(wù)器:收到ACK, 立即分配資源
既然三次握手也液銀顫不是100%可靠, 那四次,五次,六次。。。呢? 其實都一樣,不管多少次都有丟包問題。
client 只發(fā)送一個 SYN, server 分配一個tcb, 放入syn隊列中。 這時候連接叫
半連接
狀態(tài);如果server 收不到 client 的ACK, 會不停重試 發(fā)送 ACK-SYN 給client 。重試間隔 為 2 的 N 次方 疊加(2^0 , 2^1, 2^2 ….);直至超時才釋放syn隊列中的這個 TCB;
在半連接狀態(tài)下, 一方面會占用隊列配額資源,另一方面占用內(nèi)存資源。我們應(yīng)該讓半連接狀態(tài)存在時間盡可能的小
當(dāng)client 向一個未打開的端口發(fā)起連接請求時,會收到一個RST回復(fù)包
當(dāng)listen 的 backlog 和 somaxconn 都設(shè)置了得時候, 取兩者min值
Recv-Q 是accept 隊列當(dāng)前個數(shù), Send-Q 設(shè)置更大值
這種SYN洪水攻擊是一種常見攻擊方式,就是利用半連接隊列特性,占滿syn 隊列的 資源,導(dǎo)致 client無法連接上。
解決方案:
為什么不像握手那樣合并成三次揮手? 因為和剛開始連接情況,連接是大家都從0開始, 關(guān)閉時有歷史包袱的。server(被動關(guān)閉方) 收到 client(主動關(guān)閉方) 的關(guān)閉請求FIN包。 這時候可能還有未發(fā)送完的數(shù)據(jù),不能丟棄。 所以需要分開。事實可能是這樣
當(dāng)然,在沒有待發(fā)數(shù)據(jù),并且允許 Delay ACK 情況下, FIN-ACK合并還是非常常見的事情,這是三次揮手是可以的。
同上
CLOSE_WAIT 是被動關(guān)閉方才有的狀態(tài)
。
被動關(guān)閉方 到 期間的狀態(tài)為 CLOSE_WAIT, 這個狀態(tài)仍然能發(fā)鬧敗送數(shù)據(jù)。 我們叫做
半關(guān)閉
, 下面用個例子來分析:
這個是我實際生產(chǎn)環(huán)境碰到的一個問題,長連接會話場景,server端收到client的rpc call 請求1,處理發(fā)現(xiàn)請求包有問題,就強制關(guān)閉結(jié)束這次會話, 但是 因為client 發(fā)送 第二次請求之前,并沒有去調(diào)用recv,所以并不知道 這個連接被server關(guān)閉, 繼續(xù)發(fā)送 請求2 , 此時是半連接,能夠成功發(fā)送到對端機器,但是recv結(jié)果后,搏兆遇到連接已經(jīng)關(guān)閉錯誤。
如果 client 和 server 恰好同時發(fā)起關(guān)閉連接。這種情況下,兩邊都是主動連接,都會進入 TIME_WAIT狀態(tài)
1、
被動關(guān)閉方在LAST_ACK狀態(tài)(已經(jīng)發(fā)送FIN),等待主動關(guān)閉方的ACK應(yīng)答,但是 ACK丟掉, 主動方并不知道,以為成功關(guān)閉。因為沒有TIME_WAIT等待時間,可以立即創(chuàng)建新的連接, 新的連接發(fā)送SYN到前面那個未關(guān)閉的被動方,被動方認(rèn)為是收到錯誤指令,會發(fā)送RST。導(dǎo)致創(chuàng)建連接失敗。
2、
主動關(guān)閉方斷開連接,如果沒有TIME_WAIT等待時間,可以馬上建立一個新的連接,但是前一個已經(jīng)斷開連接的,延遲到達的數(shù)據(jù)包。 被新建的連接接收,如果剛好seq 和 ack字段 都正確, seq在滑動窗口范圍內(nèi)(只能說機率非常小,但是還是有可能會發(fā)生),會被當(dāng)成正確數(shù)據(jù)包接收,導(dǎo)致數(shù)據(jù)串包。 如果不在window范圍內(nèi),則沒有影響( 發(fā)送一個確認(rèn)報文(ack 字段為期望ack的序列號,seq為當(dāng)前發(fā)送序列號),狀態(tài)變保持原樣)
TIME_WAIT 問題比較比較常見,特別是CGI機器,并發(fā)量高,大量連接后段服務(wù)的tcp短連接。因此也衍生出了多種手段解決。雖然每種方法解決不是那么完美,但是帶來的好處一般多于壞處。還是在日常工作中會使用。
1、改短TIME_WAIT 等待時間
這個是之一個想到的解決辦法,既然等待時間太長,就改成時間短,快速回收端口。但是實際情況往往不樂觀,對于并發(fā)的機器,你改多短才能保證回收速度呢,有時候幾秒鐘就幾萬個連接。太短的話,就會有前面兩種問題小概率發(fā)生。
2、禁止Socket lingering
這種情況下關(guān)閉連接,會直接拋棄緩沖區(qū)中待發(fā)送的數(shù)據(jù),會發(fā)送一個RST給對端,相當(dāng)于直接拋棄TIME_WAIT, 進入CLOSE狀態(tài)。同樣因為取消了 TIME_WAIT 狀態(tài),會有前面兩種問題小概率發(fā)生。
3、tcp_tw_reuse
net.ipv4.tcp_tw_reuse選項是 從 TIME_WAIT 狀態(tài)的隊列中,選取條件:1、remote 的 ip 和端口相同, 2、選取一個時間戳小于當(dāng)前時間戳; 用來解決端口不足的尷尬。
現(xiàn)在端口可以復(fù)用了,看看如何面對前面TIME_WAIT 那兩種問題。 我們仔細(xì)回顧用一下前面兩種問題。
都是在新建連接中收到老連接的包導(dǎo)致的問題
, 那么如果我能在新連接中識別出此包為非法包,是不是就可以丟掉這些無用包,解決問題呢。
需要實現(xiàn)這些功能,需要擴展一下tcp 包頭。 增加 時間戳字段。 發(fā)送者 在每次發(fā)送的時候。 在tcp包頭里面帶上發(fā)送時候的時間戳。 當(dāng)接收者接收的時候,在ACK應(yīng)答中除了TCP包頭中帶自己此時發(fā)送的時間戳,并且把收到的時間戳附加在后面。也就是說ACK包中有兩個時間戳字段。結(jié)構(gòu)如下:
那我們接下來一個個分析tcp_tw_reuse是如何解決TIME_WAIT的兩個問題的
4、tcp_tw_recycle
tcp_tw_recycle 也是借助 timestamp機制。顧名思義, tcp_tw_reuse 是復(fù)用 端口,并不會減少 TIME-WAIT 數(shù)量。你去查詢機器上TIME-WAIT 數(shù)量,還是 幾千幾萬個,這點對有強迫癥的同學(xué)感覺很不舒服。tcp_tw_recycle 是 提前 回收 TIME-WAIT資源。會減少 機器上 TIME-WAIT 數(shù)量。
關(guān)于linux 長連接的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guān)注本站。
創(chuàng)新互聯(lián)【028-86922220】值得信賴的成都網(wǎng)站建設(shè)公司。多年持續(xù)為眾多企業(yè)提供成都網(wǎng)站建設(shè),成都品牌建站設(shè)計,成都高端網(wǎng)站制作開發(fā),SEO優(yōu)化排名推廣服務(wù),全網(wǎng)營銷讓企業(yè)網(wǎng)站產(chǎn)生價值。
網(wǎng)站標(biāo)題:Linux長連接:穩(wěn)定高效的網(wǎng)絡(luò)通信方式(linux長連接)
當(dāng)前網(wǎng)址:http://fisionsoft.com.cn/article/ccsspeo.html


咨詢
建站咨詢
