The goal of this assignment is to make sure you have experience writing simple programs using sockets. There are two independent pieces: a client program, which can be used to talk to existing servers (e.g., web servers), and a server program that can talk to existing clients (in particular,telnet
). Your client implements, roughly, the functionality oftelnet
. Your server implements the echo service. While you can use your client to talk to your service, the two are really independent, so you can build and debug one entirely before starting on the second.
The actualtelnet
is a program (and a protocol) used to establish connections to remote machines. It's the old, insecure version of what we now usessh
for. At the heart oftelnet
is establishing a TCP connection with a remote port. That's the only part we're implementing; anything you might read about the telnet protocol is a complication beyond what this assignment is asking for.Your client should be invoked something like this:
It's first argument is a host name, and its second a port number. It tries to open a TCP connection to that host/port. If it succeeds, it then sends whatever is typed to the destination. It also concurrently prints whatever is sent from the destination. That's pretty much everything. (Note that the server may not send anything back in response to an input line, or may send something even before the user has typed anything.)$ java telnet www.cs.washington.edu 80
There are two design complications you have to face, but we don't care what you do about them. The first is how the user terminates your program. One possibility is that there is some special character (or character sequence) that acts as a quit command, e.g., ctrl-D. The upside of that approach is that this it's pretty clean. The downside is that the user has no way to send whatever your command is to the other end. A less clean, but possibly easier to implement, solution is to require the user to ctrl-C to get out of your program. (Technically, the second option is a special case of the first, I suppose.)
The second (and similar, in nature) complication is what to do about normal line editing. For example, if the person using your client program types
tesin<backspace><backspace>ting
, should you send to the server the seven characterstesting
or should you send the eleven characters actually typed? Does it send each character as it is typed, or only when the user types a newline? Do you send the newline? Again, you can decide whichever seems right to you.To test your client, you can connect as in the command above, and then type these three lines (the last one being an empty line):
GET /index.html HTTP/1.1 Host: www.cs.washington.eduThat's anHTTP
request asking for what you normally think of ashttp://www.cs.washington.edu/index.html
. If your client is working, a lot of text will come be printed.
Your server opens a TCP socket and waits for clients to connect to it. It should be invocable in two ways that look a lot like this:In the first form, the user is indicating what port it wants the server to listen on. In the second, the server is asked to just use an ephemeral port. (When invoked this second way, the server should print out the port number it is listening on.)$ java echo 2345
$ java echoThe server waits for client connections. When one is established, it simply reads whatever is sent to it and sends it back. This means that if you connect to your server using the actual
telnet
utility (or your own) you should see whatever you typed repeated.One feature not to overlook is that more than one client can connect to a single echo server at a time, and each client's input should be echoed back promptly.
There are two somewhat challenging pieces to building both the client and the server. First, you have to figure out what the correct set of socket calls is for each case.Second, notice that both programs need to be doing more than one thing at a time: the client needs to be both reading from the keyboard, so it can send that data to the other end, and reading from the socket, so it can be printing. The server needs to be able to converse with multiple clients at a time. There are various implementation approaches that let you do this, but I think by far the easiest one is to use multiple threads. For the client program, one thread sits in a loop reading the keyboard and writing the socket, and another just the opposite. For the server program, there is a thread per active client, each sitting in a loop reading the socket and then writing the socket.
These programs are not long. My client is 56 lines of Java (including blank lines and my usual over abundance of comments). The server is 47 lines. Nonetheless, they can be frustrating, because there are probably a lot of new details to work out: how/when to start/stop threads; how to read from a socket; how to write to a socket; etc.
You can implement in either Java or C/C++. (Other language choices are possible by prior approval.) If I were you, I'd choose whichever I was most comfortable with, remembering that I had to use threads. I wrote sample solutions in Java, and since I don't know Java very well I spent most of the hour it took me to do this assignment trying to figure out lines like this one:
I admit it's pretty frustrating to have to spend time sorting through documentation to figure out how to say the thing you know perfectly well you want to say. The narrow goal of this assignment is to gain experience programming with sockets, though, and this is unfortunately part of it.BufferedReader in = new BufferedReader( new InputStreamReader(System.in) );
Nope.
turnin
your code files (I expect there will be two, but the number is up to you), plus a file namedREADME.txt
. In theREADME
explain:
- How to build each program. A specific cut-and-paste-able command line would be good.
- How to terminate execution of each program.
- A sentence or two explaining what decisions you made for how the client program should behave, along the lines of the issues raised in the section about it above.
- A paragraph or so explaining either why your decisions are the right ones for this kind of program (the client), or else why you made them even though they were the wrong ones.
These functions are so standard that it's got to be easy to find full program solutions sitting around on the web. Finding them, copying them, and turning them in isn't useful to anyone. Remember that the point of this assignment is not that we need 55 working copies of telnet and echo, it's entirely the experience of having built them. You'll know if you're having an appropriate experience, or if you aren't, so that should be the standard you apply in deciding what you're "allowed" to use and what you aren't.
telnet
exists, and is documented everywhere.echo
existed, but I haven't been able to find a site still running it. (It runs on port 7, if it's running.)- To make this assignment as simple as possible, there is no skeleton code.
We'll look at the README
file and at the code.
We might build the code. We might run the code. We might
compare the code with a vast inventory of sample programs
we've collected from web searches. We might compare the code
with other code turned in for this assignment.
This assignment is intended to be small-ish. If you have programmed with sockets before, the odds are you'll find it trivial. But, I don't expect you've programmed with sockets before, and I expect that you don't have much experience with threads. Summing all that up, I'm guessing that most people will need between 2 and 10 hours to complete this work. I think a few people will need a lot more (that's just statistics - I'm not thinking of anyone in particular). As usual, it would be wise to try to find your 2 to 10 hours earlier than later.