Using standard read() and write() calls on a socket in C [duplicate] - c

This question already has answers here:
What is the Difference Between read() and recv() , and Between send() and write()?
(9 answers)
Closed 7 years ago.
Is there anything bad with using read() and write() on a socket fd, instead of send() and recv()? I thought about using that in my program because read() and write() are much simpler than send() and recv().

No, there's nothing wrong with it, man 7 socket tells you explicitly that you can use the standard calls on them.
Though the send and recv functions aren't really hard to use, you can just pass 0 as the flags argument to get the same behavior as plain read and write.

Related

Is the write() function in C blocking or non-blocking?

I looked on the Linux man pages for the answer but can't seem to find it. I know that read() is blocking but I'm still not sure about write().
Can anyone point me to any documentation for clarification?
Read POSIX on read() and
write(). See also functions such as open() and pipe().
It depends on the attributes of the file descriptor you're reading from or writing to (think O_NONBLOCK, for example), and on the underlying file type (disk file vs pipe vs FIFO vs socket vs character or block special), and so on.
Succinctly, both read() and write() can be blocking or non-blocking, depending on circumstances.

How to check if a TCP connection was closed by peer gracefully or not WITHOUT READING FROM IT? [duplicate]

This question already has answers here:
c++ how to use select to see if a socket has closed
(4 answers)
Closed 6 years ago.
I'm using Linux.
Can someone provide me an example of how to use select() or poll() to check whether a TCP connection was closed by peer through FIN or terminated by RST?
poll() can detect RST with setting POLLHUP or POLLERR in revents, but select() has no facilities like this.
In my test, when socket is terminated by RST, socket error got by getsockopt will be ECONNRESET. Is this a effective way or not?
Is it necessary to determine how the connection was closed?
Thanks!
If the socket was closed gracefully, the socket will be set for read.
Then, when you read, you will receive 0 data read because you got to EOF. You can also check with
ioctl(sock, FIONREAD, &n);
to determine if there is data to read. Here you have an example: c++ how to use select to see if a socket has closed
According to select man: "readfds will be watched to see if characters become available for reading (more precisely, to see if a read will not block; in particular, a file descriptor is also ready on end-of-file)"
If there is a pending socket error, the corresponding bit will be set in readfds or writefds. Then read or recv should return error. Also you can use this to determine if there is a pending error in the socket:
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &result, &resultLen) < 0) {
//getsockopt ERROR
} else if (result == 0) {
//NO ERROR
} else {
//SOCKET ERROR
}

Detect closed connection on non blocking socket

I'm really sorry if my question is a duplicate, but I didn't find useful infos in the site.
I'm using non blocking sockets and a select(). How can I detect if a client closed the connection on non-blocking socket? I saw that a read() returns -1 with errno = EWOULDBLOCK when no datas are available to be read and also when a connection is closed.
How can I discriminate above cases?
When the peer has closed the connection:
select() will return the socket as readable.
A recv() or read() on the socket will return zero.
I saw that a read() returns -1 with errno = EWOULDBLOCK when no datas are available to be read
Correct, but the connection isn't closed.
and also when a connection is closed.
No you didn't. That's not correct. It returns zero.
How can I discriminate above cases?
They aren't the same, and they don't manifest themselves in the same way.
When the peer had closed the connection for a specific socket, a call to read() on this socket would return 0. This behaviour is independent from the socket's blocking state.
From man 2 read (italics by me):
RETURN VALUE
On success, the number of bytes read is returned (zero indicates end of file)

How I can check if it something available in socket? [duplicate]

This question already has answers here:
How to check amount of data available for a socket in C and Linux
(6 answers)
Closed 7 years ago.
I write a simple application that provide connection between two computers in C. I have a problem with simultaneously reading and writing in socket. I am able to check if user press any key by getch(), but I don't know how to check if it something in socket buffer. When I use read() function it wait until be something in socket. I wanted to check socket buffer and then use read(), but I can't find any function/flag to check this. Maybe is different solution for this problem, perhaps use another thread to read?
You can use sys/ioctl.h file's method ioctl:
#include <sys/ioctl.h>
...
int count;
ioctl(fd, FIONREAD, &count);
Reference credit : This Answer

Bytes waiting in pipe [duplicate]

This question already has answers here:
Determine the size of a pipe without calling read()
(13 answers)
Closed 9 years ago.
I am writing a remote terminal application and i use pipes to take data from a child process' stdout/stderr to then send it to a client. Specifically, I am running Linux, and I don't really care about portability (if the solution is Linux-only, it's OK).
I need to know how many bytes have currently been written to, but not yet read from, the pipe. I was Googling for a long time and couldn't find an answer. I need to read as many bytes from the pipe as possible without blocking.
Is this possible? Thank you for help.
The only way to do this is to attempt a read and count how many bytes you get. recv with MSG_PEEK can do that.
Your best bet will be to set your read end of the pipe to non blocking and then just read ahead. If your file descriptor is set to non blocking, you read on it and the pipe is empty then you well get EAGAIN error in errno. This will indicate to you that the pipe is still open, but just empty at the moment.
You can set your file descriptor to non block with
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK);
Then read:
while (read(fd, buffer, sizeof(buffer))) {
if (errno == EAGAIN) {} // buffer currently empty
else if (errno) {perror("read")} // an error happened
}

Resources