If I got a file descriptor (socket fd), how to check this fd is avaiable for read/write? In my situation, the client has connected to server and we know the fd. However, the server will disconnect the socket, are there any clues to check it ?
如果我有一个文件描述符(socket fd),如何检查这个fd是否可用于读/写?在我的情况下,客户端已连接到服务器,我们知道fd。但是,服务器会断开套接字,是否有任何检查线索?
5 个解决方案
#1
You want fcntl()
to check for read/write settings on the fd:
您希望fcntl()检查fd上的读/写设置:
#include <unistd.h>
#include <fcntl.h>
int r;
r = fcntl(fd, F_GETFL);
if (r == -1)
/* Error */
if (r & O_RDONLY)
/* Read Only */
else if (r & O_WRONLY)
/* Write Only */
else if (r & O_RDWR)
/* Read/Write */
But this is a separate issue from when the socket is no longer connected. If you are already using select()
or poll()
then you're almost there. poll()
will return status nicely if you specify POLLERR
in events
and check for it in revents
.
但这与套接字不再连接时的问题是一个单独的问题。如果你已经在使用select()或poll(),那么你几乎就在那里。如果在事件中指定POLLERR并在revents中检查它,poll()将很好地返回状态。
If you're doing normal blocking I/O then just handle the read/write errors as they come in and recover gracefully.
如果您正在进行正常的阻塞I / O,那么只需处理读/写错误,它们会进入并正常恢复。
#2
You can use select()
or poll()
for this.
您可以使用select()或poll()。
#3
In C#, this question is answered here
在C#中,这个问题在这里得到解答
In general, socket disconnect is asynchronous and needs to be polled for in some manner. An async read on the socket will typically return if it's closed as well, giving you a chance to pick up on the status change quicker. Winsock (Windows) has the ability to register to receive notification of a disconnect (but again, this may not happen for a long time after the other side "goes away", unless you use some type of 'keepalive' (SO_KEEPALIVE, which by default may not notice for hours, or an application-level heartbeat).
通常,套接字断开是异步的,需要以某种方式进行轮询。套接字上的异步读取通常会在它关闭时返回,这样您就有机会更快地了解状态更改。 Winsock(Windows)能够注册以接收断开连接的通知(但同样,这可能不会在另一方“消失”后很长一段时间内发生,除非你使用某种类型的'keepalive'(SO_KEEPALIVE,通过默认可能不会注意几个小时或应用程序级心跳)。
#4
I found the recv can check. when socket fd is bad, some errno is set.
我发现recv可以检查。当socket fd坏的时候,设置了一些errno。
ret = recv(socket_fd, buffer, bufferSize, MSG_PEEK);
if(EPIPE == errno){
// something wrong
}
#5
Well, you could call select(). If the server has disconnected, I believe you'll eventually get an error code returned... If not, you can use select() to tell whether you're network stack is ready to send more data (or receive it).
好吧,你可以调用select()。如果服务器断开连接,我相信你最终会得到一个错误代码返回...如果没有,你可以使用select()来告诉你网络堆栈是否已准备好发送更多数据(或接收它)。
#1
You want fcntl()
to check for read/write settings on the fd:
您希望fcntl()检查fd上的读/写设置:
#include <unistd.h>
#include <fcntl.h>
int r;
r = fcntl(fd, F_GETFL);
if (r == -1)
/* Error */
if (r & O_RDONLY)
/* Read Only */
else if (r & O_WRONLY)
/* Write Only */
else if (r & O_RDWR)
/* Read/Write */
But this is a separate issue from when the socket is no longer connected. If you are already using select()
or poll()
then you're almost there. poll()
will return status nicely if you specify POLLERR
in events
and check for it in revents
.
但这与套接字不再连接时的问题是一个单独的问题。如果你已经在使用select()或poll(),那么你几乎就在那里。如果在事件中指定POLLERR并在revents中检查它,poll()将很好地返回状态。
If you're doing normal blocking I/O then just handle the read/write errors as they come in and recover gracefully.
如果您正在进行正常的阻塞I / O,那么只需处理读/写错误,它们会进入并正常恢复。
#2
You can use select()
or poll()
for this.
您可以使用select()或poll()。
#3
In C#, this question is answered here
在C#中,这个问题在这里得到解答
In general, socket disconnect is asynchronous and needs to be polled for in some manner. An async read on the socket will typically return if it's closed as well, giving you a chance to pick up on the status change quicker. Winsock (Windows) has the ability to register to receive notification of a disconnect (but again, this may not happen for a long time after the other side "goes away", unless you use some type of 'keepalive' (SO_KEEPALIVE, which by default may not notice for hours, or an application-level heartbeat).
通常,套接字断开是异步的,需要以某种方式进行轮询。套接字上的异步读取通常会在它关闭时返回,这样您就有机会更快地了解状态更改。 Winsock(Windows)能够注册以接收断开连接的通知(但同样,这可能不会在另一方“消失”后很长一段时间内发生,除非你使用某种类型的'keepalive'(SO_KEEPALIVE,通过默认可能不会注意几个小时或应用程序级心跳)。
#4
I found the recv can check. when socket fd is bad, some errno is set.
我发现recv可以检查。当socket fd坏的时候,设置了一些errno。
ret = recv(socket_fd, buffer, bufferSize, MSG_PEEK);
if(EPIPE == errno){
// something wrong
}
#5
Well, you could call select(). If the server has disconnected, I believe you'll eventually get an error code returned... If not, you can use select() to tell whether you're network stack is ready to send more data (or receive it).
好吧,你可以调用select()。如果服务器断开连接,我相信你最终会得到一个错误代码返回...如果没有,你可以使用select()来告诉你网络堆栈是否已准备好发送更多数据(或接收它)。