监听socket,连接socket
文章目录
【注意】最后更新于 October 25, 2022,文中内容可能已过时,请谨慎使用。
监听socket,连接socket
监听 socket 是指已经 【socket,bind,listen】 listen 会创建一个监听队列
连接 socket 是 accept 函数从监听队列中获取一个客户端连接,这个连接称为连接 socket
https://man7.org/linux/man-pages/man2/select.2.html
https://man7.org/linux/man-pages/man3/select.3p.html
I/O 复用 select 函数
PHP 函数 stream_select()
内部调用 select(nfs,readfds,writefds,exceptfds,timeout)系统函数
select 参数解析
- nfs → 被监听的文件描述符的总数 socket 文件
- readfds → 读事件对应的文件描述符集合
- writefds → 写事件对应的文件描述符集合
- exceptfds → 异常事件对应的文件描述符集合
- timeout → 超时时间,设置为 0 即立马返回,NULL 为阻塞到有事件发生
nfs 监听到对应的事件后,会修改对应事件的文件描述符并生成新的文件描述符返回,文件描述符 id+1,比如【3,4】两个客户端连接上来,【4】客户端发送消息,select 会监听到这个修改,修改【4】的文件描述符并命名为【5】,并返回【5】文件描述符
文件描述符产生就绪事件
可读事件
- socket 内核接受缓冲区的字节数大于或等于 SO_RCVLOWAT 水位标记时,执行读操作时返回的字节数大于 0
- 对端关闭时,此时的读操作返回 0
- 监听 socket 上有新客户端连接时
- socket 上有未处理错误,可使用 getsocketopt 来读取和清除错误
可写事件
- socket 内核发送缓冲区的可用字节数大于等于 SO_SNDLOWAT 水位标记时,执行写操作,返回的字节数大于 0
- 对端关闭时,写操作会触发 SIGPIPE 中断信号
- socket 有未处理错误
异常事件
就是发送紧急数据【带外数据】时
当计算机网卡接受到数据时,会把数据写入到内存中,并向 CPU 发起硬件中断请求,CPU 会响应去执行中断服务程序,并把数据【会根据端口号找到 socket 文件描述符】写入到对应的 socket 内核接受缓冲区中,同时唤醒当前的进程【select 有返回值】