Reputation: 15973
I am trying to read from a blocking socket, but I am wondering that read()
returns -1, which I think means that there's currently no data to read - I would expect that it blocks until it can read the amount of bytes.
I also tried ensuring that the socket is in blocking mode and that a high timeout is set using:
int setBlockingIO(int fd)
{
int flags = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, flags & (~O_NONBLOCK));
int nTimeout = 30000; // 30 seconds
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&nTimeout, sizeof(int));
}
But this hasn't changed anything.
My question:
read()
will really block?
I know that there's another question on this topic, but there I cannot find the answer for my question.
UPDATE
Without setting a timeout, read()
also returns (subjectivly) immediately -1
UPDATE 2
errno
is 107 (ENOTCONN, Transport endpoint is not connected)
.
But the client side has not closed the connection in the meanwhile (ensured by a long sleep()
after write()
)
Upvotes: 2
Views: 4656
Reputation: 634
read()
could block, so if there's no data available it will return -1
and set errno
to EAGAIN
or EWOULDBLOCK
.
If you wand to use read()
, you could use select()
or poll()
to wait for availability of data on the socket.
Upvotes: 0
Reputation: 15973
I've solved the problem.
Thank you for all your comments, they had been a great help.
The problem was the usage of the wrong file descriptor.
I passed the file descriptor of the server socket to read()
, instead of the file descriptor of the client socket which accept()
returned.
Upvotes: 0
Reputation: 215387
What do you expect? You said you have a non-blocking socket so of course it does not block. The behavior for a non-blocking socket on read
is to immediately return with some data (possibly shorter than the requested amount) if data is available to read, and to return -1 with errno
set to EAGAIN
or EWOULDBLOCK
if no data is available.
If you don't want non-blocking behavior, why did you set the socket to be non-blocking?
Edit: Grr, you've changed your question. The reason for ENOTCONN
is that you're trying to read from a socket that is not connected. Unless a socket was obtained by accept
or socketpair
, you must call connect
on it to connect it to a remote address before read
will work.
Upvotes: 4
Reputation: 32530
It means that either there was a time-out, or possibly a signal interrupted the read. You can use the results of errno
in errno.h
to see what the error is, and if you want the error in a human-readable formating, you can use either strerror()
or perror()
from string.h
or stdlib.h
Update: According to the POSIX specification, you should be passing a struct timeval
(defined in sys/time.h
) set to the desired number of seconds and microseconds before a timeout occurs to setsockopt
when specifying the SO_RCVTIMEO
flag rather than casting an int
to a const char*
. So even though your client may be mis-behaving and causing a different error right now, you could still end up with problems further down the line if you're sending the wrong argument types to the function.
Upvotes: 3
Reputation: 6167
The reason is in errno. Likely scenarios:
[ECONNRESET]
The d argument refers to a socket, and the remote
socket end is forcibly closed.[EAGAIN]
The file was marked for non-blocking I/O, and no data
were ready to be read.Basically, you make non-blocking blocking using:
do
{
read(...);
} while(errno == EAGAIN);
Upvotes: 2
Reputation: 76908
It returns -1 when it times out.
Don't set a timeout and it will block forever (Well, at least while the socket is still connected, anyway).
Upvotes: 1