1

I have an assignment that implements a Client-server chat room in C. I've got most of it down, but have got stuck on the client-side with regard to select().

When a client connects to the server, he doesn't send anything unless the user actually inputs something to stdin. However, he should still receive all the messages that are either broadcast to all users or aimed specifically at him.

Ex.:

  1. C1, C2, C3 are connected and talking
  2. C4 connects, but says nothing. C1/2/3 still talking.
  3. C1/2/3 see nothing with regard to C4 (except that he connected), but C4 sees all the messages that C1/2/3 have been sending since he connected.

So in essence, the client should block upon reading but still receive messages (quite contradictory!). The only way I can think of right now would be to make the client multi-threaded with one thread listening for receive, and the other for sending; or using fork().

My question is the following: Is there an easier way to do the above with select()? Would select still do the trick if, say, I add stdin to my write_fds and both stdin the socket that is used to connect to the server to my read_fds (since I would need to read from both) and pass those to select()? Since TCP is full-duplex, there should be no issues when/if a read and a write happen at the same time, correct?

I guess essentially, what I want to implement is a simple telnet session for all of my clients. Any suggestions to that end would be quite welcome.

EDIT:

Something I neglected to mention: I am well aware that I can use FD_ISSET to both check if the server sent something and if the client sent something, but I see no way to make those behave the way I want it to. That is, I see no way to still receive something while "blocking" on send - perhaps adding a timer to the select() and periodically polling both the socket and stdin? I will attempt that and edit this post further, but any suggestions are quite welcome in the meantime.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
filpa
  • 3,651
  • 8
  • 52
  • 91
  • It seems to me that you should take a look at telnet source code to see how it's done there, since you're aware that it can solve your problem. `select()` is certainly a reasonable option, as is multithreading. – mah Nov 13 '13 at 20:52
  • You want to wait until *input* is available on either `stdin` or the socket. You want to read from potentially both of them. – Ian McLaird Nov 13 '13 at 20:52
  • @mah I am doing that right now; I was merely curious whether `select() ` has the capability of doing what I described so I wasn't looking for something that's not there. Ian, good point - I will update my post to reflect that. – filpa Nov 13 '13 at 20:55
  • I seem to recall doing this assignment when I was in college. I didn't need threads. You should be able to make this work by simply `select`ing on `stdin` and your socket. Waiting for `stdin` to be writable seems a bit silly. – Ian McLaird Nov 13 '13 at 21:07
  • @IanMcLaird My apologies for the late reply; How would I do that, though? To actually read from stdin I do have to use something like `fgets` - which blocks. These uses are contradictory, no? – filpa Nov 14 '13 at 17:27
  • See this question. http://stackoverflow.com/questions/717572/how-do-you-do-non-blocking-console-i-o-on-linux-in-c – Ian McLaird Nov 14 '13 at 17:42

0 Answers0