|
Experiment 5.2
Assuming that you have already done Experiment 5.1 you have already obtained and compiled the chat server and client.
Chapter Notes 5.1 5.2 5.3 After testing the programs you move on to the first modification, adding a name for each. (Tip: when testing do not use Harry and Sally, use Client and Server. It makes things a lot easier, especially if you have short-term memory problems.) I used a
printf
followed by agets
. If you just add those two lines along with a variable for the name, you will get a compiler warning. You should do that if you are somewhat new to C even though I am about to tell you how to avoid it. Hint: in the absence of any indication as to the type returned by a function, what does the C compiler assume? Now the fix: just addstring.h
to the files you are including. Why did that fix the problem?In order to prepend the name to the message you need to use
strcat
. This is harder to do in C than in C++, say, because you need to use astrcpy
followed by twostrcat
functions.This small step has an important implication for testing. Depending on where you put this code you may encounter the following oddity: you fire up your server and while it is still waiting for the name, you fire up your client which immediately terminates. Why?
The first Optional Extension is very interesting! It requires slightly different behavior when sending and receiving depending on whether it is the first time through. Straightforward, but my first effort met a fascinating problem. The client sent data and then, somehow, received data before the server had a chance to respond. Then the two got out of sync, each being in input mode. For my own sanity in debugging I cleared buffers right after each use. Voila! The problem was gone. Apparently, the function
readln
did not provide theNULL
termination. When I later usedstrlen
to determine how many bytes to send, I was way over and somehow overwrote myconnection
variable.The second Optional Extension seems at first blush to be easy, almost trivial. It is not! You would probably first try to use
getchar
in a loop. This will not do what you want. What makes this extension difficult is that you need to change the mode of your keyboard so that it will not buffer the input until a line-feed. I found it quite difficult to do in the given context, that is, working with the code provided, so I cheated. I took a simpler, self-contained chat program and modified that code. There are two ways to do this, and each involves its own intricacies. The simpler way is use a system call. On a Linux box you code
system("stty cbreak")
before your chat session code and
system("stty -cbreak")
after it. On Solaris 8 you use
raw
in place ofcbreak
.What this does is change the settings of your keyboard so that input is not buffered, ie, the program does not wait for a
\n
but really accepts a single character. The problem is that your keyboard behavior is changed in other ways as well. You will certainly have a loop in which you read a character fromstdin
and send one character to the other host. This loop will terminate when the user hits theEnter
key. Normally, the test would be a comparison with\n
. I found (Solaris 8) that it was a\r
! The session should terminate when one or the other user hitsControl-D
. That would normally mean a test forEOF
, -1, but with the keyboard mode alterred, I found that I needed to test forEOT
, 4. How do you figure this out? You usegdb
, and you examine the value of your variable at the appropriate point. In other words you experiment!An alternate approach, preferred by Professor Comer, is to write code to modify the keyboard settings. This involves the functions
tcgetattr
andtcsetattr
. I wrote a fuction with one parameter and called it twice. Everything worked fine except that I had to test forEOT
instead ofEOF
as described above.Please do not be turned off by these comments. This is a very interesting and rewarding exercise. I personally found a great deal of satisfaction in it, and think how much better you are prepared for its challenges than I was!
This site is maintained by by W. David Laverell of the Computer Science Department at Calvin College.
For assistance or corrections, please contact him at lave@calvin.edu.