The only thing that's cooler than saying that your program is multi-threaded is, of course, saying that it's "client-server". Bonus points if you can throw in something like "thin-client" or "n-tiered". What do these terms actually mean? You should probably know, on the off chance that you get the one in a million manager who knows what they're talking about :-). A client-server architecture is one where the application, or more correctly, the system, consists of two or more programs. The client is the user front end to the system. It is what will run on the users desktop, or in the browser. The client can be either a "thick" client, which means that most of the processing logic and computation is done by the client program, and summaries are passed back to the server, or it can be a "thin" client, which means that it is mostly an empty UI that passes back all input to the server for processing. In previous times, the thick client was the norm, because it distributed the load of processing across many desktops, rather than asking one server to do all the work. As servers became more powerful, the thin client came into ascendency, because it was far easier to do updates; if the processing logic changes, but the client-server api stays the same, there is no need to update umpteen desktops to update the logic. The server is what runs on the host system. There is normally only one server in a client-server app, although there may be load balanced servers, or failover servers, that afford high availablity. The server is usually responsable for managing multiple clients, that connect to the server over a network. The server handles their requests, processes whatever needs to be processed, and sends back responses to the client. The server is normally in the same language as the clients, but this is not a requirement. You can have a server written in C, and clients written in Java that connect to it, as long as they are "talking" in the same language. After all, strings and ints are strings and ints. So, a normal client server application could be considered to be "2-tiered", where the client is one tier, and the server a second. client ----------------------- server tier 1 tier 2 An N-tiered application is one where there are more steps in this pathway. n-tiered applications usually have some sort of collector, or filter, or translator acting as a proxy between the client and the server, or they have separated the processing on the server side from the data/mail servers, or some other configuration of a similar nature. client ---------------- server ---------------- database client ---------------- translator ------------ server So, how does the client talk to the server? The connection is typically made over a network, using some sort of network protocol to communicate between the two programs. The most ubiquitous example of client server programming today is the internet. The browser is a client, and it connects to a web server, and makes requests using HTTP. FTP clients, SSH clients, even your terminals, are client server applications. How is the connection made between the client and the server? Each computer has a unique address called an IP (Internet Protocol) address. This identifies a computer on a network. The address is a set of four numbers, from 0 - 255, that will uniquely define a machine. For example the IP of armstrong is 128.205.32.3 yeager is 128.205.36.9. This number is sort of like a telephone number, with each successive sequence more closely identifying the location of the computer. Most machines also have a DNS (Domain Name System) name, which is the user-friendly (or human friendly) way to get to computers. For example, you can get to armstrong by typing ssh armstrong.cse.buffalo.edu, as well as by typing ssh 128.205.32.3. The DNS name is simply a mapping from a human readable name to its unique IP address. Each host machine also has a number of ports. Ports are sort of like frequencies on the radio, or extensions to a phone system; each one provides a sub-address that you can talk to the host computer on. Some ports have standard designations; for example, all internet web traffic comes to port 80, and all e-mail goes out from port 25. There are standard ports for SSH, and Telnet, and most of the other standard services. On unix, all ports from 0-1023 are reserved for root level processes. However, higher ports are open for client server applications to access. In order for your client to talk to your server, it has to know what host the server is running on, and also what port that the server is listening to for requests. The server needs to know what port to listen to. Once your server is up and running, it will open a "socket" to the port that you want it to listen to. It will wait until a client attaches to that socket, and forms a connection. You can then get an input and an output stream for the connection from that socket. These are the streams that will form the communication pathways between the client and the server. WARNING! Any time you create a client server application, you create a potential security problem. Due to the nature of network communication, you have no idea where the input that someone sends to a server is coming from. It may be from your client, or it may be from some malicious hacker. The server is running as YOU, so anything that the server does in response to a request from a client (legit or otherwise) will happen to your account. This can be bad. Thankfully, we are guarded by two things in this particular project : random port assignment, and passing arguments by java object streams. Also, the program shouldn't be affecting the file system in major ways, or recursing based on input, etc. But - it is a bad idea to have a server that accepts plain text commands like "delete filename" and then deletes things from your home directory, unless you also create some sort of security layer. Also - don't leave your server running. This is asking for trouble. See SimpleServer.java and SimpleClient.java That was pretty cool, but : When the client disconnected, the server also died. What's up with that? The server was only set up to receive a single connection. See StayaliveServer.java Ok, now we can connect and disconnect without killing the server. But what about communication back to the client? See TwoWayServer.java and TwoWayClient.java Cool! Now we have two way communication. But what about multiple clients? Well, what do we want to do with multiple clients? Do we want to process the client input simultaneously? What do we do when we want to do two (or more) things simultaneously in a program? Hint - no needles required for this one. See MultiServer.java But what about asynchronous communication? With a tight loop between the send to the server and the response, the server can't send unsolicited messages to the clients. The main while loop in the client controls server send and receive. How do we set it up so that the client can recieve messages back from the server? Hint : This application is starting to look more like a tapestry... See MultiSocketClient.java and MultiSocketServer.java Things to think about - how would you handle server shutdown? How about decoupling the servers tight loop for accepting clients?