用AI赚第一桶💰低成本搭建一套AI赚钱工具,源码可二开。 广告
1. epoll需要把socket设置为非阻塞么。 * 结论: * 对于监听的 listenfd,最好使用**水平触发模式**,**边缘触发模式会导致高并发情况下,有的客户端会连接不上**。如果非要使用边缘触发,可以用 while 来循环 accept()。 * **在水平模式下 connfd**,阻塞非阻塞是一样的。在边缘模式下,必须使用非阻塞。 * 理由: * **边缘模式 监听的socket**,,在高并发时,如果没有一次处理完所有请求,则会出现客户端连接不上的问题。不需要讨论 listenfd 是否阻塞,因为 epoll_wait() 返回的必定是已经就绪的连接,所以不管是阻塞还是非阻塞,accept() 都会立即返回。 * **如果使用的是阻塞socket,在边缘模式下 connfd**,如果不读取一个事件下的所有数据则会干扰下一个事件,所以需要嵌套一层循环,这样才能完整的处理数据。因为外层次嵌套了一层循环,则会在数据读完了之后会卡在recv上,因为是阻塞io,如果没数据可读,它会一直等在那里,直到有数据可读。但是这个时候,如果用另一个客户端去连接服务器,服务器就不能受理这个新的客户端了。 * 如果使用的是非阻塞socket,边缘模式下,和阻塞版本一样,必须在读取数据的外部套一层循环,这样才能完整的处理数据。因为非阻塞 IO 如果没有数据可读时,会立即返回,并设置 errno。这里我们根据 **EAGAIN** 和 **EWOULDBLOCK** 来判断数据是否全部读取完毕了,如果读取完毕,就会正常退出循环了。 * 建议: 监听listenfd使用水平模式,连接的connfd 使用边缘模式+非阻塞。 2.非阻塞的socket,设置socket为非阻塞,需要设置recv的flags为非阻塞么,如果设置recv的flags参数为非阻塞则需要设置socket为非阻塞么。