## socket

PHP網絡編程
*****
### websocket
*****
### 調試相關linux命令
1. 查看某端口的socket連接數量:
```shell
netstat -n | grep 9999
netstat -n | grep 9999 | grep TIME_WAIT
netstat -n | grep 9999 | grep ESTABLISHED
netstat -n | grep 9999 |wc -l
```
注意socket連接有一些狀態:`TIME_WAIT`、`ESTABLISHED`(TIME_WAIT狀態時,過一會看就會消失,其實已經是關閉了的,應該是為了復用之類的吧)
*****
## 其他
> 腳本意外結束,socket會怎么樣,實測是過一會自動斷掉,不信你結束腳本,在執行試試就知道了,不過一段時間再次執行提示端口占用
*****
### 參考
[Linux Socket編程(不限Linux) - 吳秦 - 博客園](https://www.cnblogs.com/skynet/archive/2010/12/12/1903949.html)
> **socket一詞的起源:** 在組網領域的首次使用是在1970年2月12日發布的文獻[IETF RFC33](http://datatracker.ietf.org/doc/rfc33/)中發現的,撰寫者為Stephen Carr、Steve Crocker和Vint Cerf。根據美國計算機歷史博物館的記載,Croker寫道:“命名空間的元素都可稱為套接字接口。一個套接字接口構成一個連接的一端,而一個連接可完全由一對套接字接口規定。”計算機歷史博物館補充道:“這比BSD的套接字接口定義早了大約12年。”
[TCP的粘包問題以及數據的無邊界性_C語言中文網](http://c.biancheng.net/cpp/html/3041.html)
[TCP粘包問題分析和解決(全) - 小 樓 一 夜 聽 春 雨 - 博客園](https://www.cnblogs.com/kex1n/p/6502002.html)
[socket原理詳解 - 老皮肉 - 博客園](https://www.cnblogs.com/sheseido/p/11617993.html)
> 當我們使用不同的協議進行通信時就得使用不同的接口,還得處理不同協議的各種細節,這就增加了開發的難度,軟件也不易于擴展。于是UNIX BSD就發明了socket這種東西,socket屏蔽了各個協議的通信細節,使得程序員無需關注協議本身,直接使用socket提供的接口來進行互聯的不同主機間的進程的通信。
>
> 我們發現,socket確實和進程很像,就像我們把具體的進程看成是程序的一個實例,**同樣我們也可以把具體的socket看成是網絡通信的一個實例。**
[高性能網絡編程(一)----accept建立連接_陶輝:聚焦分布式系統的程序員-CSDN博客](https://blog.csdn.net/russell_tao/article/details/9111769)
>[tip] 下面這些文章鏈接可能已不可用,最新地址可以查看這里:[Socket編程 - 老李秀 | 可能是東半球第二程序員...](https://t.ti-node.com/node/134-1)
[PHP socket初探 --- 關于IO的一些枯燥理論](https://blog.ti-node.com/blog/6389362802519179264)
> 用php的fopen打開文件關閉文件讀讀寫寫,這叫本地文件IO.在socket編程中,本質就是網絡IO.
[PHP socket初探 --- 一些零碎細節的拾漏補缺(一)](https://blog.ti-node.com/blog/6405406800828432384)
>socket_accept也是阻塞的,雖然有while,但是由于accpet是阻塞的,所以這段代碼不會進入無限死循環中
>
> 所以每當詢問一次socket_accept后得到的反饋都是“沒有連接”,所以就直接走到“客戶端連接失敗”的分支中去了,而且是不斷的不停的。這個時候,你用htop或者top命令查看服務器CPU,不出意外應該是100%,這是非阻塞的極大缺點。
>[danger] 只要不是 **不斷的不停的無限循環**(**正確的使用無限循環是一種讓程序持久運行的方法**),就不會出現CPU使用率100%,比如每次循環睡眠一下,**當然理想的實現還是讓程序阻塞掛起。**
>
> **不斷的不停的無限循環** 運行一會就會使cpu占用飆升到100%,一會兒程序就要奔潰了。
[PHP socket初探 --- 先從一個簡單的socket服務器開始](https://blog.ti-node.com/blog/6382424397004668928)
> socket的中文名字叫做套接字,這種東西就是對TCP/IP的“封裝”。
> 在php中,可以操控socket的函數一共有兩套,一套是socket*系列的函數,另一套是stream系列的函數。socket_是php直接將C語言中的socket抄了過來得到的實現,而stream*系則是php使用流的概念將其進行了一層封裝。
>
> 此處將會阻塞住,一直到有客戶端來連接服務器。**阻塞狀態的進程是不會占據CPU的**(相當于掛起等待IO),所以你不用擔心while循環會將機器拖垮,不會的
[PHP socket初探 --- select系統調用](https://blog.ti-node.com/blog/6389426571769282560)
> 利用預fork派生進程服務于多個客戶端的服務器,這種服務器的進程模型基本上的大概原理其實跟我們常用的apache是非常相似的.
> epoll,目前的最終解決版,解決c10k問題的功臣
[PHP socket初探 --- 顫顫抖抖開篇epoll(一)](https://blog.ti-node.com/blog/6389748959052562432)
[PHP socket初探 --- 硬著頭皮繼續libevent(二)](https://blog.ti-node.com/blog/6396317917192912897)
> 下面我們從開始寫一個php定時器來步入到代碼的節奏中。定時器是大家常用的一個工具,一般phper一說定時器,腦海中第一個想起的絕逼是Linux中的crontab。難道phper們離開了crontab真的就沒法混了嗎?是的,真的好羞恥,現實告訴我們就是這樣的,他們離開了crontab真的就沒法混了。那么,是時候通過純php來搞一波兒定時器實現了!
[PHP socket初探 --- 含著淚也要磕完libevent(三)](https://blog.ti-node.com/blog/6402083150796685313)
[雨林寒舍 | php基于libevent實現并發socket服務端](https://www.im050.com/posts/366)
[《TCP/IP詳解 卷1:協議》在線閱讀版(全網唯一) - 即時通訊開發者社區!](http://www.52im.net/topic-tcpipvol1.html?mobile=no)
[PHP socket 你們都用在什么場景上? - V2EX](https://www.v2ex.com/amp/t/431229)
[https://github.com/hoaproject](https://github.com/hoaproject)
[https://github.com/amphp](https://github.com/amphp)
[https://github.com/amphp/amp](https://github.com/amphp/amp)
[https://amphp.org/amp/](https://amphp.org/amp/)
[https://github.com/reactphp](https://github.com/reactphp)
[https://github.com/nrk/predis](https://github.com/nrk/predis)
[https://github.com/weiboad/kafka-php](https://github.com/weiboad/kafka-php)
[https://github.com/hprose/hprose-php](https://github.com/hprose/hprose-php)
[http://pecl.php.net/package/uv](http://pecl.php.net/package/uv)
[http://pecl.php.net/package/ev](http://pecl.php.net/package/ev)
[libev與libuv的區別 - blcblc - 博客園](https://www.cnblogs.com/charlesblc/p/6341280.html)
[https://www.workerman.net/](https://www.workerman.net/)
[驚群問題 | 復現 | 解決](https://mp.weixin.qq.com/s/iCBaXgUiyPxNLmquEvtCEg)
[叮咚 | 同步異步阻塞非阻塞](https://mp.weixin.qq.com/s/llNV9hnVQslBcnufQ4gqzg)
[認認真真的聊聊中斷](https://mp.weixin.qq.com/s/bTfeI5p4eO5j6I9edeV73g)
[一個簡單的Linux下的socket程序_C語言中文網](http://c.biancheng.net/cpp/html/3030.html)
多進程都監聽著socket會不會有并發問題,會不會都會被操作系統喚醒?
[為什么epoll是線程安全?](https://zhuanlan.zhihu.com/p/30937065)
[多線程調用epoll\_wait()的線程安全問題分析](https://blog.csdn.net/wangyin159/article/details/48176783)
[epoll的幾個操作函數是線程安全嗎-?表示懷疑~](http://blog.sina.cn/dpool/blog/s/blog_6aafad1501012rdo.html)
> 驚群是良性的,任何fd都不會被分配給多個進程
[5個步驟,教你瞬間明白線程和線程安全_CSDN資訊-CSDN博客](https://blog.csdn.net/csdnnews/article/details/82321777)
> 當多個線程訪問某個方法時,不管你通過怎樣的調用方式、或者說這些線程如何交替地執行,我們在主程序中不需要去做任何的同步,這個類的結果行為都是我們設想的正確行為,那么我們就可以說這個類是線程安全的。
[圖解 | 深入揭秘 epoll 是如何實現 IO 多路復用的!](https://mp.weixin.qq.com/s/OmRdUgO1guMX76EdZn11UQ)
~~~
多個進程監聽同一個端口,epol 系統調用會有并發問題嗎,底層保證了原子性吧,應該能保證多個進程同時調用的并發安全性,不然上層就麻煩了。
不管上層怎么并發調用,但是操作系統只有一個啊,所以系統層調用不會有并發問題,只有一個系統,和誰并發啊,自己同時和自己啊,所以沒有并發問題。
有并發問題的情況都是因為,多個操作不是原子不可分割的,中間有間隙,導致可能被其他操作插入。
并發問題根本原因都是因為這個間隙,如果不存在這個間隙問題,也就沒有并發問題了。
系統調用沒有這個間隙,所以沒有并發問題
并發時的業務安全問題,簡稱 并發問題
~~~
[圖解 | 深入理解高性能網絡開發路上的絆腳石 - 同步阻塞網絡 IO](https://mp.weixin.qq.com/s/cIcw0S-Q8pBl1-WYN0UwnA)
~~~
IO是單詞 ipunt output 兩個單詞的首字母縮寫,字面意思是 輸入輸出,所以對應到不同的設備,表示的意義不一樣,如對控制臺程序來說,指輸入和輸出,對于磁盤來說,只讀取和寫入,對網絡設備來說,指接受和發送。
----
io復用與阻塞io的區別, 前者阻塞在select系統調用上(同時阻塞在多個 socket io上),可以同時檢測多個io,而阻塞io是阻塞在具體io上,只能同時檢測一個io。
----
io復用的精髓在于 阻塞在 select 系統調用上,而非 阻塞在 socket accept 上,這樣單個進程就能接受多個連接了,并發連接的上限取決于 進程中 $client 變量 若能使用的內存大小,這就是 多個連接復用在少數的幾個進程的精髓。
每個連接,請求都需要響應嗎。不響應客戶端怎么知道成功了呢,應該是協議規定是否需要響應吧,如http協議就必須每個請求都需要立即得到響應。
不過還是不太明白, socket accept 也能實現類似的效果(也有地方說 這種阻塞 每個連接需要獨立的進程/線程單獨處理,其實是不能實現 io復用,因為阻塞,所以不知道 哪個連接上面有可讀,不能只看連接),不也是io復用嗎,連接的本質是什么,四元組嗎。還是要熟悉底層,看源碼才能完全理解。
----
連接的本質是雙方達成的一種約定,約定有效連接就有效,并不是像所謂的兩根線建立的連接那樣的現實形態。
----
異步可以提高效率和并發能力,如 去餐廳買豆漿和油條,兩個窗口排隊,假設分別要2分鐘,那么最后總共要4分鐘,如果是異步的,兩個窗口只叫號,最終時間會在2分鐘左右,效率提升了,提升的部分就是在一個窗口等待而不能做別的事情的時間。
提高并發能力也不能單純依靠更多的進程,不然時間都消耗在資源爭奪上及進程切換上了,在資源有限時更少的進程利用事件驅動可能有更好的并發性能。
高性能就是要 多快好省
~~~
~~~
https://mp.weixin.qq.com/s/sFIZE3egB2Tfnz2rylv-1Q
結論就是實際上Libevent并不是線程安全的,如果你要在多線程(進程)中使用時候,注意EventBase最好不要共享,如果一定要共享同一個EventBase對象,你就只能給這個EventBase對象加鎖...
打開一個文件句柄
多進程共享復制了一份了這個文件句柄,當一個進程關閉文件,其他進程中的文件句柄資源還是有效的,但是對其進行操作時肯定會報錯。這是因為php層可以同時存在多個相同的句柄,進程復制了資源,但是對操作系統來說,只有一個文件句柄,釋放了就沒有了,也就是其他進程持有了舊句柄了。
所以進程共享資源的問題要看資源的本質是什么,這里文件句柄資源的本質是操作系統分配的,操作系統只有一個,而不是看上層抽象的資源。
assertion ctx failed in evmap_io_active
~~~
~~~
產出關鍵字讓函數變成了生成器,即可迭代的數據結構,可遍歷,每一個元素就是一次執行,產出關鍵字將函數執行結構分割成元素。
簡單說就是函數結構可以分多次執行
----
八月八爬蟲,獲取詳情 異常又要重試,但重試沒必要再次獲取列表,可以用 生成器,重啟變成接著上次的地方開始
~~~
~~~
文本代碼,語義文本
轉換為指令
系統調用
進程,多進程,各種系統調用,系統資源,網絡資源,用戶態與內核態
。。。。。
代碼 與 程序 之間是有鴻溝的,需要轉換視角才能理解對方,對底層不熟悉的人需要理解這點,代碼 與 程序 并不能直接對等理解。
語義代碼里面的類,對象,屬性,函數,變量 等會存在于進程中,不過在進程中可能是計算機資源了,而不是文本代碼的語義形式了。
一個代碼轉換成指令執行后,可能變成多個進程,或使用多個網絡資源,這中間是有鴻溝的,如何理解 代碼語義 和 進程 以及網絡資源之間 的關系是很重要的,要理解最重要的是先理解你寫的代碼是如何最終在計算機中運行的,怎么起到控制計算機的作用。
~~~
----
[stream_socket_server() 和 socket_create() - workerman問答社區](https://wenda.workerman.net/question/4439)
[Walkerman 源代碼中關于socket_import_stream疑問 - workerman問答社區](https://wenda.workerman.net/question/873)
[Socket 理解之內核調用 TIME_WAIT 深入理解 | LearnKu 產品論壇](https://learnku.com/articles/60187)
[socket 到底是個啥](https://mp.weixin.qq.com/s/Ebvjy132eRDOmcIL5cmxJw)
*****
[從一次經歷談 TIME_WAIT 的那些事 | 酷 殼 - CoolShell](https://coolshell.cn/articles/22263.html)
> 我們來看主動斷鏈接的最后一個狀態`TIME_WAIT`后就不需要等待對端回 ack了,而是進入了超時狀態。這主要是因為,在網絡上,如果要知道我們發出的數據被對方收到了,那我們就需要對方發來一個確認的Ack信息,那問題來了,對方怎么知道自己發出去的ack,被收到了?難道還要再ack一下,這樣ack來ack回的,那什么誰也不要玩了……是的,這就是比較著名的【兩將軍問題】——兩個將軍需要在一個不穩定的信道上達成對敵攻擊時間的協商,A向B派出信鴿,我們明早8點進攻,A怎么知道B收到了信?那需要B向A派出信鴿,ack說我收到了,明早8點開干。但是,B怎么知道A會收到自己的確認信?是不是還要A再確認一下?**這樣無窮無盡的確認導致這個問題是沒有完美解的**(我們在《[分布式事務](https://coolshell.cn/articles/10910.html#Two_Generals_Problem%EF%BC%88%E4%B8%A4%E5%B0%86%E5%86%9B%E9%97%AE%E9%A2%98%EF%BC%89)》一文中說過這個問題,這里不再重述)
----
last update:2018-10-18 23:30:31
- 開始
- 公益
- 更好的使用看云
- 推薦書單
- 優秀資源整理
- 技術文章寫作規范
- SublimeText - 編碼利器
- PSR-0/PSR-4命名標準
- php的多進程實驗分析
- 高級PHP
- 進程
- 信號
- 事件
- IO模型
- 同步、異步
- socket
- Swoole
- PHP擴展
- Composer
- easyswoole
- php多線程
- 守護程序
- 文件鎖
- s-socket
- aphp
- 隊列&并發
- 隊列
- 講個故事
- 如何最大效率的問題
- 訪問式的web服務(一)
- 訪問式的web服務(二)
- 請求
- 瀏覽器訪問阻塞問題
- Swoole
- 你必須理解的計算機核心概念 - 碼農翻身
- CPU阿甘 - 碼農翻身
- 異步通知,那我要怎么通知你啊?
- 實時操作系統
- 深入實時 Linux
- Redis 實現隊列
- redis與隊列
- 定時-時鐘-阻塞
- 計算機的生命
- 多進程/多線程
- 進程通信
- 拜占庭將軍問題深入探討
- JAVA CAS原理深度分析
- 隊列的思考
- 走進并發的世界
- 鎖
- 事務筆記
- 并發問題帶來的后果
- 為什么說樂觀鎖是安全的
- 內存鎖與內存事務 - 劉小兵2014
- 加鎖還是不加鎖,這是一個問題 - 碼農翻身
- 編程世界的那把鎖 - 碼農翻身
- 如何保證萬無一失
- 傳統事務與柔性事務
- 大白話搞懂什么是同步/異步/阻塞/非阻塞
- redis實現鎖
- 淺談mysql事務
- PHP異常
- php錯誤
- 文件加載
- 路由與偽靜態
- URL模式之分析
- 字符串處理
- 正則表達式
- 數組合并與+
- 文件上傳
- 常用驗證與過濾
- 記錄
- 趣圖
- foreach需要注意的問題
- Discuz!筆記
- 程序設計思維
- 抽象與具體
- 配置
- 關于如何學習的思考
- 編程思維
- 談編程
- 如何安全的修改對象
- 臨時
- 臨時筆記
- 透過問題看本質
- 程序后門
- 邊界檢查
- session
- 安全
- 王垠
- 第三方數據接口
- 驗證碼問題
- 還是少不了虛擬機
- 程序員如何談戀愛
- 程序員為什么要一直改BUG,為什么不能一次性把代碼寫好?
- 碎碎念
- 算法
- 實用代碼
- 相對私密與絕對私密
- 學習目標
- 隨記
- 編程小知識
- foo
- 落盤
- URL編碼的思考
- 字符編碼
- Elasticsearch
- TCP-IP協議
- 碎碎念2
- Grafana
- EFK、ELK
- RPC
- 依賴注入
- 科目一
- 開發筆記
- 經緯度格式轉換
- php時區問題
- 解決本地開發時調用遠程AIP跨域問題
- 后期靜態綁定
- 談tp的跳轉提示頁面
- 無限分類問題
- 生成微縮圖
- MVC名詞
- MVC架構
- 也許模塊不是唯一的答案
- 哈希算法
- 開發后臺
- 軟件設計架構
- mysql表字段設計
- 上傳表如何設計
- 二開心得
- awesomes-tables
- 安全的代碼部署
- 微信開發筆記
- 賬戶授權相關
- 小程序獲取是否關注其公眾號
- 支付相關
- 提交訂單
- 微信支付筆記
- 支付接口筆記
- 支付中心開發
- 下單與支付
- 支付流程設計
- 訂單與支付設計
- 敏感操作驗證
- 排序設計
- 代碼的運行環境
- 搜索關鍵字的顯示處理
- 接口異步更新ip信息
- 圖片處理
- 項目搭建
- 閱讀文檔的新方式
- mysql_insert_id并發問題思考
- 行鎖注意事項
- 細節注意
- 如何處理用戶的輸入
- 不可見的字符
- 抽獎
- 時間處理
- 應用開發實戰
- python 學習記錄
- Scrapy 教程
- Playwright 教程
- stealth.min.js
- Selenium 教程
- requests 教程
- pyautogui 教程
- Flask 教程
- PyInstaller 教程
- 蜘蛛
- python 文檔相似度驗證
- thinkphp5.0數據庫與模型的研究
- workerman進程管理
- workerman網絡分析
- java學習記錄
- docker
- 筆記
- kubernetes
- Kubernetes
- PaddlePaddle
- composer
- oneinstack
- 人工智能 AI
- 京東
- pc_detailpage_wareBusiness
- doc
- 電商網站設計
- iwebshop
- 商品規格分析
- 商品屬性分析
- tpshop
- 商品規格分析
- 商品屬性分析
- 電商表設計
- 設計記錄
- 優惠券
- 生成唯一訂單號
- 購物車技術
- 分類與類型
- 微信登錄與綁定
- 京東到家庫存系統架構設計
- crmeb
- 命名規范
- Nginx https配置
- 關于人工智能
- 從人的思考方式到二叉樹
- 架構
- 今日有感
- 文章保存
- 安全背后: 瀏覽器是如何校驗證書的
- 避不開的分布式事務
- devops自動化運維、部署、測試的最后一公里 —— ApiFox 云時代的接口管理工具
- 找到自己今生要做的事
- 自動化生活
- 開源與漿果
- Apifox: API 接口自動化測試指南