ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## socket ![](http://cdn.aipin100.cn/68d6a55a1a37649141d4f82d937a3ffc) 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