摘要:原文地址的中文名字叫做套接字,這種東西就是對的封裝。運(yùn)行結(jié)果如下簡單解析一下上述代碼來說明一下服務(wù)器的流程首先,根據(jù)協(xié)議族或地址族套接字類型以及具體的的某個協(xié)議來創(chuàng)建一個。很容易受到攻擊,造成拒絕服務(wù)。
[原文地址:https://blog.ti-node.com/blog...]
socket的中文名字叫做套接字,這種東西就是對TCP/IP的“封裝”?,F(xiàn)實(shí)中的網(wǎng)絡(luò)實(shí)際上只有四層而已,從上至下分別是應(yīng)用層、傳輸層、網(wǎng)絡(luò)層、數(shù)據(jù)鏈路層。最常用的http協(xié)議則是屬于應(yīng)用層的協(xié)議,而socket,可以簡單粗暴的理解為是傳輸層的一種東西。如果還是很難理解,那再粗暴地點(diǎn)兒tcp://218.221.11.23:9999,看到?jīng)]?這就是一個tcp socket。
socket賦予了我們操控傳輸層和網(wǎng)絡(luò)層的能力,從而得到更強(qiáng)的性能和更高的效率,socket編程是解決高并發(fā)網(wǎng)絡(luò)服務(wù)器的最常用解決和成熟的解決方案。任何一名服務(wù)器程序員都應(yīng)當(dāng)掌握socket編程相關(guān)技能。
在php中,可以操控socket的函數(shù)一共有兩套,一套是socket_系列的函數(shù),另一套是stream_系列的函數(shù)。socket_是php直接將C語言中的socket抄了過來得到的實(shí)現(xiàn),而stream_系則是php使用流的概念將其進(jìn)行了一層封裝。下面用socket_*系函數(shù)簡單為這一系列文章開個篇。
先來做個最簡單socket服務(wù)器:
將文件保存為server.php,然后執(zhí)行php server.php運(yùn)行起來??蛻舳宋覀兪褂胻elnet就可以了,打開另外一個終端執(zhí)行telnet 127.0.0.1 9999按下回車即可。運(yùn)行結(jié)果如下:
簡單解析一下上述代碼來說明一下tcp socket服務(wù)器的流程:
1.首先,根據(jù)協(xié)議族(或地址族)、套接字類型以及具體的的某個協(xié)議來創(chuàng)建一個socket。
2.第二,將上一步創(chuàng)建好的socket綁定(bind)到一個ip:port上。
3.第三,開啟監(jiān)聽linten。
4.第四,使服務(wù)器代碼進(jìn)入無限循環(huán)不退出,當(dāng)沒有客戶端連接時,程序阻塞在accept上,有連接進(jìn)來時才會往下執(zhí)行,然后再次循環(huán)下去,為客戶端提供持久服務(wù)。
上面這個案例中,有兩個很大的缺陷:
1.一次只可以為一個客戶端提供服務(wù),如果正在為第一個客戶端發(fā)送helloworld期間有第二個客戶端來連接,那么第二個客戶端就必須要等待片刻才行。
2.很容易受到攻擊,造成拒絕服務(wù)。
分析了上述問題后,又聯(lián)想到了前面說的多進(jìn)程,那我們可以在accpet到一個請求后就fork一個子進(jìn)程來處理這個客戶端的請求,這樣當(dāng)accept了第二個客戶端后再fork一個子進(jìn)程來處理第二個客戶端的請求,這樣問題不就解決了嗎?OK!擼一把代碼演示一下:
將代碼保存為server.php,然后執(zhí)行php server.php,客戶端依然使用telnet 127.0.0.1 9999,只不過這次我們開啟兩個終端來執(zhí)行telnet。重點(diǎn)觀察當(dāng)?shù)谝粋€客戶端連接上去后,第二個客戶端時候也可以連接上去。運(yùn)行結(jié)果如下:
通過接受到客戶端請求的時間戳可以看到現(xiàn)在服務(wù)器可以同時為N個客戶端服務(wù)的。但是,接著想,如果先后有1萬個客戶端來請求呢?這個時候服務(wù)器會fork出1萬個子進(jìn)程來處理每個客戶端連接,這是會死人的。fork本身就是一個很浪費(fèi)系統(tǒng)資源的系統(tǒng)調(diào)用,1W次fork足以讓系統(tǒng)崩潰,即便當(dāng)下系統(tǒng)承受住了1W次fork,那么fork出來的這1W個子進(jìn)程也夠系統(tǒng)內(nèi)存喝一壺了,最后是好不容易費(fèi)勁fork出來的子進(jìn)程在處理完畢當(dāng)前客戶端后又被關(guān)閉了,下次請求還要重新fork,這本身就是一種浪費(fèi),不符合社會主義主流價值觀。如果是有人惡意攻擊,那么系統(tǒng)fork的數(shù)量還會呈直線上漲一直到系統(tǒng)崩潰。
所以,我們就再次提出增進(jìn)型解決方案。我們可以預(yù)估一下業(yè)務(wù)量,然后在服務(wù)啟動的時候就fork出固定數(shù)量的子進(jìn)程,每個子進(jìn)程處于無限循環(huán)中并阻塞在accept上,當(dāng)有客戶端連接擠進(jìn)來就處理客戶請求,當(dāng)處理完成后僅僅關(guān)閉連接但本身并不銷毀,而是繼續(xù)等待下一個客戶端的請求。這樣,不僅避免了進(jìn)程反復(fù)fork銷毀巨大資源浪費(fèi),而且通過固定數(shù)量的子進(jìn)程來保護(hù)系統(tǒng)不會因無限fork而崩潰。
將文件保存為server.php后php server.php執(zhí)行,然后再用ps -ef | grep phpserver | grep -v grep來看下服務(wù)器進(jìn)程狀態(tài):
可以看到master進(jìn)程存在,除此之外還有10個子進(jìn)程處于等待服務(wù)狀態(tài),再同一個時刻可以同時為10個客戶端提供服務(wù)。我們通過telnet 127.0.0.1 9999來嘗試一下,運(yùn)行結(jié)果如下圖:
好啦,php新的征程系列就先通過一個簡單的入門開始啦!下篇將會講述一些比較深刻的理論基礎(chǔ)知識。
[原文地址:https://blog.ti-node.com/blog...]
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/29367.html
摘要:原文地址在初探先從一個簡單的服務(wù)器開始中依次講解了三個逐漸進(jìn)步的服務(wù)器只能服務(wù)于一個客戶端的服務(wù)器利用可以服務(wù)于多個客戶端的額服務(wù)器利用預(yù)派生進(jìn)程服務(wù)于多個客戶端的服務(wù)器最后一種服務(wù)器的進(jìn)程模型基本上的大概原理其實(shí)跟我們常用的是非常 [原文地址:https://blog.ti-node.com/blog...] 在<PHP socket初探 --- 先從一個簡單的socket服務(wù)器開始...
摘要:原文地址要想更好了解編程,有一個不可繞過的環(huán)節(jié)就是在中,一切皆文件實(shí)際上要文件干啥不就是讀寫么所以,這句話本質(zhì)就是才是王道用的打開文件關(guān)閉文件讀讀寫寫,這叫本地文件在編程中,本質(zhì)就是網(wǎng)絡(luò)所以,在開始進(jìn)一步的編程前,我們必須先從概念上認(rèn)識好 [原文地址:https://blog.ti-node.com/blog...] 要想更好了解socket編程,有一個不可繞過的環(huán)節(jié)就是IO.在Lin...
摘要:原文地址正如標(biāo)題所言,顫顫抖抖開篇。于是只能是你自己,把單子上的個快遞逐次和收到的對比一遍,然后對比完畢后再把這個單子給了阿梅,然后阿梅繼續(xù)等。剃光頭前的阿梅,就是,不敢正眼看老板娘一眼。剃光頭后的阿梅,就是,可徒手接魔鬼隊(duì)的死亡之球。 [原文地址:https://blog.ti-node.com/blog...] 正如標(biāo)題所言,顫顫抖抖開篇epoll。顫顫抖抖的原因大概也就是以前幾乎...
摘要:原文前面可以說是弄了一系列的和多進(jìn)程的一大坨內(nèi)容,知識淺顯代碼粗暴風(fēng)格簡陋,總的說來,還是差了一些細(xì)節(jié)。今天,就一些漏掉的細(xì)節(jié)補(bǔ)充一下。最后,我補(bǔ)充一句是同步的,而不是異步。 原文:https://t.ti-node.com/thread/... 前面可以說是弄了一系列的php socket和多進(jìn)程的一大坨內(nèi)容,知識淺顯、代碼粗暴、風(fēng)格簡陋,總的說來,還是差了一些細(xì)節(jié)。今天,就一些漏...
閱讀 332·2025-02-07 13:40
閱讀 502·2025-02-07 13:37
閱讀 786·2024-11-06 13:38
閱讀 972·2024-09-10 13:19
閱讀 1166·2024-08-22 19:45
閱讀 1439·2021-11-19 09:40
閱讀 2719·2021-11-18 13:14
閱讀 4351·2021-10-09 10:02