对于socket接口(指connect/send/recv/accept..等等后面不重复,不包括不能设置非阻塞的如select),在阻塞模式下有可能因为发生信号,返回EINTR错误,由用户做重试或终止。
但是,在非阻塞模式下,是否出现这种错误呢?
对此,重温了系统调用、信号、socket相关知识,得出结论是:
不会出现。
首先,
1.信号的处理是在用户态下进行的,也就是必须等待一个系统调用执行完了才会执行进程的信号函数,所以就有了信号队列保存未执行的信号
2.用户态下被信号中断时,内核会记录中断地址,信号处理完后,如果进程没有退出则重回这个地址继续执行
socket接口是一个系统调用,也就是即使发生了信号也不会中断,必须等socket接口返回了,进程才能处理信号。
也就是,EINTR错误是socket接口主动抛出来的,不是内核抛的。socket接口也可以选择不返回,自己内部重试之类的..
那阻塞的时候socket接口是怎么处理发生信号的?
举例
socket接口,例如recv接口会做2件事情,
1.检查buffer是否有数据,有则复制清除返回
2.没有数据,则进入睡眠模式,当超时、数据到达、发生错误则唤醒进程处理
socket接口的实现都差不了太多,抽象说
1.资源是否立即可用,有则返回
2.没有,就等...
对于
1.这个时候不管有没信号,也不返回EINTR,只管执行自己的就可以了
2.采用睡眠来等待,发生信号的时候进程会被唤醒,socket接口唤醒后检查有无未处理的信号(signal_pending)会返回EINTR错误。
所以
socket接口并不是被信号中断,只是调用了睡眠,发生信号睡眠会被唤醒通知进程,然后socket接口选择主动退出,这样做可以避免一直阻塞在那里,有退出的机会。非阻塞时不会调用睡眠。
我们看看linux内核里的实现
linux kernel 3.5.5
参考资料:
《UNIX环境高级编程》
《UNIX网络编程》
《TCP/IP详解 卷2:实现》
《深入Linux内核架构》
- 大小: 30.6 KB
- 大小: 51.5 KB
- 大小: 25.4 KB
分享到:
相关推荐
CWSocket类可能通过设置socket的O_NONBLOCK标志实现了非阻塞模式。 多线程是现代应用程序处理并发任务的关键技术。在C++中,可以使用标准库中的std::thread或者在MFC中使用CWinThread来创建和管理线程。CWSocket类...
Linux 客户端Socket 非阻塞 connect 编程详解 本文档详细介绍了 Linux 客户端 Socket 非阻塞 connect 编程的实现方法和原理。非阻塞 connect 是一种高效的网络编程技术,能够提高程序的性能和可靠性。 一、非阻塞 ...
4. **错误处理**:在非阻塞模式下,读写操作可能会返回错误,如`EAGAIN`或`EWOULDBLOCK`,这时不应视为异常,而是应该重新安排任务,等待合适时机再尝试。 5. **多线程或RTOS集成**:在FreeRTOS这样的实时操作系统...
对于非阻塞Socket,可以通过`fcntl()`函数设置文件描述符的标志位,添加`O_NONBLOCK`标志,使Socket处于非阻塞模式。在这种模式下,如果尝试读写数据时没有准备好,系统不会等待而是立即返回错误,从而避免了程序的...
值得注意的是,非阻塞socket在没有数据可读或无法写入时不会等待,而是立即返回错误(通常是`EAGAIN`或`EWOULDBLOCK`),这要求程序员需要适当地处理这些错误,使用`select`、`poll`或`epoll`等机制来检查socket的...
在非阻塞模式下,`recvfrom()`和`sendto()`系统调用会在没有数据可用时返回EWOULDBLOCK错误,而不是挂起线程。这使得服务器可以处理其他任务,提高并发处理能力。 创建非阻塞UDP服务器的关键步骤如下: 1. **创建...
在非阻塞模式下,如果连接尚未完成,`connect()`会立即返回错误`EINPROGRESS`。 4. **I/O复用**:使用`select()`、`poll()`或`epoll()`函数监控连接状态,等待连接完成或超时。 5. **发送和接收数据**:使用`send...
2. **套接字选项SO_OOBINLINE和SO_NONBLOCK**:设置套接字为非阻塞模式通常通过设置套接字选项SO_NONBLOCK实现。这允许在没有数据可读时,recv调用返回错误而不是阻塞。同时,如果希望接收带外数据(OOB,Out-of-...
当客户端尝试从服务器读取数据时,如果服务器还没有发送任何数据,阻塞模式下的Socket会保持等待状态,直到数据到达。这可能导致客户端程序暂停执行其他任务,直到数据可用。同样,如果服务器试图向客户端发送数据,...
在C++中,可以使用`fcntl()`函数配合`F_SETFL`和`O_NONBLOCK`标志将socket设置为非阻塞模式。在这种模式下,如果数据未准备好,`recv()`和`send()`将立即返回,而不是等待,这样服务器可以继续处理其他任务。 在...
而非阻塞套接字则不同,当请求的操作不能立即完成时,它不会阻塞当前进程,而是立即返回一个错误状态,允许进程继续执行其他任务。 在Linux中,我们通常使用`fcntl`函数来设置套接字为非阻塞模式。`fcntl`函数可以...
`setsockopt()`是一个通用的接口,可以设置各种Socket选项,包括将其设置为非阻塞模式。我们可以使用`F_SETFL`标志和`O_NONBLOCK`标志来改变Socket的文件描述符标志,使其变为非阻塞。 例如,以下代码片段展示了...
- 非阻塞I/O通过设置套接字选项`O_NONBLOCK`,使得发送和接收操作在无数据时不会阻塞。 8. **错误处理**: - 在Socket编程中,错误处理至关重要,常见的错误如EINTR(中断系统调用)、ECONNREFUSED(连接被拒绝)...
1. **设置套接字为非阻塞模式**:使用`fcntl()`函数的`F_SETFL`标志和`O_NONBLOCK`选项,将TCP套接字设置为非阻塞模式。 2. **轮询检查**:使用`select()`、`poll()`或`epoll`等I/O多路复用机制,定期检查连接的就绪...
使用`fcntl(fd, F_SETFL, O_NONBLOCK)`,其中`fd`是文件描述符,`O_NONBLOCK`标志表示非阻塞模式。 2. **select()** 和 **poll()** 系统调用:这两个函数可以监控多个文件描述符,当它们准备就绪时(即有数据可读或...
通过`fcntl(fd, F_SETFL, O_NONBLOCK)`这一调用,我们可以将指定的文件描述符设置为非阻塞模式。 3. **read和write函数**:在非阻塞模式下,`read()`和`write()`函数的行为会发生变化。如果缓冲区无数据可读或无...
这是因为在连接时,我们不知道服务器是否在线,如果不设置非阻塞状态,可能会导致程序阻塞。 其次,在调用 connect 函数连接对端主机时,如果失败,需要判断当前的 errno 是否为 EINPROGRESS,也就是说是不是连接...
7. **非阻塞模式**:通过设置`O_NONBLOCK`标志,可以使Socket在没有数据可读或无法写入时不会阻塞程序。 8. **多线程/异步处理**:对于高并发的网络应用,可能需要使用多线程或多进程,或者异步I/O模型(如epoll)...
但在某些情况下,如网络拥塞,可能会出现数据丢失或乱序,这时需要通过序列号、确认应答等机制来恢复。 10. **缓冲区管理**:send和recv操作可能会受到操作系统内核缓冲区的影响,因此在设计应用程序时要考虑缓冲区...
非阻塞套接字(Non Block Socket)是网络编程中的一个重要概念,特别是在高并发和实时性要求较高的系统中。在传统的阻塞模式下,当一个套接字进行读写操作时,如果数据没有准备好,调用会挂起,直到数据准备完毕才会...