0

I'd like to replicate the following ruby code of a simple forking TCP echo server in C:

require 'socket'

port = 3333

server = TCPServer.new(port)
puts "Starting TCPServer @ port #{port} with PID=#{Process.pid}"

loop do
  client = server.accept
  pid = fork do 
    puts "PID = #{Process.pid}"
    while (line = client.gets)
      client.write(line)
    end
    client.close_write
    exit 0
  end
  if(pid > 0)
    Process.detach(pid)
  end
end

I started with http://beej.us/guide/bgnet/examples/server.c and I changed the forking part to:

if (!fork())
  {             // this is the child process
    FILE *client = fdopen (new_fd, "r+");
    close (sockfd);     // child doesn't need the listener
    char buffer[BUFSIZ];
    while (fgets (buffer, BUFSIZ, client))
      {
    fputs (buffer, stdout);
      }
    fclose (client);
    exit (0);
  }

Basically, I'm wrapping the file descriptor of the socket in a FILE structure (fdopen(...)) in order to get fgets(...). Is this the wrong thing to do to begin with?

This whole approach seems to work if I do nc localhost 3333 (with the compiled server running) and simply type the input on the command line (lines get echoed back). However, if I do cat a_multiline_file.txt|nc localhost 3333, I only get the first line back because in that case, all except the first call to fgets() fail (I tried doing the same fgets in an infinite loop).

I'm curious to know what the cause of the problem is and how I can do line-by-line reading on a socket correctly.

EDIT:

On JoeManiaci's advice, I added: perror("Last failure"); after the while loop, which got me "Last failure: Illegal seek" for the second case. So that makes sense -- seeking doesn't make sense on sockets, and if fgets does not only buffering but seeking too, that makes the fdopen approach out of the question for sockets.

Part 2 of my question remains--how do I do line-oriented reading on sockets correctly in C?

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
  • 1
    When fgets() fails, errno is set, so you should be able to print out the error and maybe get a better idea of what is going on. – JoeManiaci Sep 03 '14 at 20:42
  • 2
    Maybe the solution proposed in [this similar discussion](http://stackoverflow.com/questions/10255663/illegal-seek-error-when-working-with-socket-streams-with-non-empty-read-buffer) on stackoverflow works for you? – user2719058 Sep 03 '14 at 22:05
  • Yes it does, user2719058! Thanks a lot! – Petr Skocik Sep 03 '14 at 22:18

0 Answers0