Using TCP Sockets as Streams (C)

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 (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.

March 2013

Sun Mon Tue Wed Thu Fri Sat
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            

About this Entry

This page contains a single entry by Marc published on September 5, 2006 4:53 PM.

Links for 03 Sep 2006 [del.icio.us] was the previous entry in this blog.

Links for 05 Sep 2006 [del.icio.us] is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.

OpenID accepted here Learn more about OpenID
Powered by Movable Type 4.21-en