For those that don't care about programming C, you can skip this entry now.
Today I learned something about C sockets that I didn't know before (and in the process fixed a bug in my code). One technique for reading and writing to a socket is to use the stream functions (
The following code allows you to
Notice I said most.
What I learned today is that if you open up a socket in read/write mode, everything works fine if your data is synchronous and you service things in order (read then write then read then write). However, if you read the stream, then write to the stream, and while you're writing more data is written from the other end, when you go to read again, you will get a read error (most likely ESPIPE (29) "Illegal Seek"). The way to fix this problem is to open up two streams, one for reading (getting data from the other side) and one for writing (sending data to the other side).
Hopefully this will help someone as it took me a little while to figure it out.
Today I learned something about C sockets that I didn't know before (and in the process fixed a bug in my code). One technique for reading and writing to a socket is to use the stream functions (
fprintf()
, fgets()
, etc.). To do that you must create a stream handle from the socket using fdopen()
, and of course make sure you clean up your mess when you are done.The following code allows you to
fprintf()
to a socket (some things skipped for brevity):
int main(int argc, char **argv) { int sock; FILE *sockfd = NULL; : // setup and accept socket here sockfd = fdopen(sock, "w"); fprintf(sockfd, "pity the foo\n"); : // do other stuff }With most streams you can open them up in read (
r
), write (w
) modes. Also you can change either one to do both read and write by adding a +
so that it's either r+
or w+
.Notice I said most.
What I learned today is that if you open up a socket in read/write mode, everything works fine if your data is synchronous and you service things in order (read then write then read then write). However, if you read the stream, then write to the stream, and while you're writing more data is written from the other end, when you go to read again, you will get a read error (most likely ESPIPE (29) "Illegal Seek"). The way to fix this problem is to open up two streams, one for reading (getting data from the other side) and one for writing (sending data to the other side).
int main(int argc, char **argv) { int sock; char buf[2048]; FILE *wsockfd = NULL, *rsockfd = NULL; : // setup and accept socket here wsockfd = fdopen(sock, "w"); rsockfd = fdopen(sock, "r"); fprintf(wsockfd, "pity the foo\n"); fgets(buf, 2048, rsock); : // do other stuff }Of course, you should error check everything, etc. Also don't get the two mixed up (try to read from the write/write to the read) or you will have other issues.
Hopefully this will help someone as it took me a little while to figure it out.