This section shows you how to write a server and the client that goes with it. The server in the client/server pair serves up Knock Knock jokes. Knock Knock jokes are favored by children and are usually vehicles for bad puns. They go like this:
- Socket Program For One Way Communication
- Write A Socket Program For Echo/ping/talk Commands In Java 1
- Write A Socket Program For Echo/ping/talk Commands In Java 10
Write a socket Program for Echo / Ping / Talk commands. Create a socket (TCP) between two computers and enable file transferbetween them. Write a program to implement Remote Command Execution (Two M/Cs mustbe used)4. Run this program by typing the following at terminal/command line. $ javac udp_server.java && java udp_server Server socket created. Waiting for incoming data. Now the udp server is up and waiting for incoming data. To check that udp server is really up, the netstat command can be used.
Server: 'Knock knock!'
Client: 'Who's there?'
Server: 'Dexter.'
Client: 'Dexter who?'
Server: 'Dexter halls with boughs of holly.'
Client: 'Groan.'
Client: 'Who's there?'
Server: 'Dexter.'
Client: 'Dexter who?'
Server: 'Dexter halls with boughs of holly.'
Client: 'Groan.'
The example consists of two independently running Java programs: the client program and the server program. The client program is implemented by a single class,
KnockKnockClient
, and is very similar to the EchoClient
example from the previous section. The server program is implemented by two classes:KnockKnockServer
andKnockKnockProtocol
. KnockKnockServer
, which is similar to EchoServer
, contains the main
method for the server program and performs the work of listening to the port, establishing connections, and reading from and writing to the socket. The classKnockKnockProtocol
serves up the jokes. It keeps track of the current joke, the current state (sent knock knock, sent clue, and so on), and returns the various text pieces of the joke depending on the current state. This object implements the protocol—the language that the client and server have agreed to use to communicate.
The following section looks in detail at each class in both the client and the server and then shows you how to run them.
The Knock Knock Server
This section walks through the code that implements the Knock Knock server program,
KnockKnockServer
.
The server program begins by creating a new
ServerSocket
object to listen on a specific port (see the statement in bold in the following code segment). When running this server, choose a port that is not already dedicated to some other service. For example, this command starts the server program KnockKnockServer
so that it listens on port 4444:
The server program creates the
ServerSocket
object in a try
-with-resources statement:
ServerSocket
is ajava.net
class that provides a system-independent implementation of the server side of a client/server socket connection. The constructor for ServerSocket
throws an exception if it can't listen on the specified port (for example, the port is already being used). In this case, the KnockKnockServer
has no choice but to exit.
If the server successfully binds to its port, then the
ServerSocket
object is successfully created and the server continues to the next step—accepting a connection from a client (the next statement in the try
-with-resources statement):
The
accept
method waits until a client starts up and requests a connection on the host and port of this server. (Let's assume that you ran the server program KnockKnockServer
on the computer named knockknockserver.example.com
.) In this example, the server is running on the port number specified by the first command-line argument. When a connection is requested and successfully established, the accept method returns a newSocket
object which is bound to the same local port and has its remote address and remote port set to that of the client. The server can communicate with the client over this new Socket
and continue to listen for client connection requests on the original ServerSocket
This particular version of the program doesn't listen for more client connection requests. However, a modified version of the program is provided inSupporting Multiple Clients.
After the server successfully establishes a connection with a client, it communicates with the client using this code:
This code does the following:
- Gets the socket's input and output stream and opens readers and writers on them.
- Initiates communication with the client by writing to the socket (shown in bold).
- Communicates with the client by reading from and writing to the socket (the
while
loop).
Step 1 is already familiar. Step 2 is shown in bold and is worth a few comments. The bold statements in the code segment above initiate the conversation with the client. The code creates a
KnockKnockProtocol
object—the object that keeps track of the current joke, the current state within the joke, and so on.
After the
KnockKnockProtocol
is created, the code calls KnockKnockProtocol
's processInput
method to get the first message that the server sends to the client. For this example, the first thing that the server says is 'Knock! Knock!' Next, the server writes the information to thePrintWriter
connected to the client socket, thereby sending the message to the client.
Step 3 is encoded in the
while
loop. As long as the client and server still have something to say to each other, the server reads from and writes to the socket, sending messages back and forth between the client and the server.
The server initiated the conversation with a 'Knock! Knock!' so afterwards the server must wait for the client to say 'Who's there?' As a result, the
while
loop iterates on a read from the input stream. The readLine
method waits until the client responds by writing something to its output stream (the server's input stream). When the client responds, the server passes the client's response to the KnockKnockProtocol
object and asks the KnockKnockProtocol
object for a suitable reply. The server immediately sends the reply to the client via the output stream connected to the socket, using a call to println. If the server's response generated from the KnockKnockServer
object is 'Bye.' this indicates that the client doesn't want any more jokes and the loop quits.
The Java runtime automatically closes the input and output streams, the client socket, and the server socket because they have been created in the
try
-with-resources statement.
The Knock Knock Protocol
The
KnockKnockProtocol
class implements the protocol that the client and server use to communicate. This class keeps track of where the client and the server are in their conversation and serves up the server's response to the client's statements. The KnockKnockProtocol
object contains the text of all the jokes and makes sure that the client gives the proper response to the server's statements. It wouldn't do to have the client say 'Dexter who?' when the server says 'Knock! Knock!'
All client/server pairs must have some protocol by which they speak to each other; otherwise, the data that passes back and forth would be meaningless. The protocol that your own clients and servers use depends entirely on the communication required by them to accomplish the task.
The Knock Knock Client
The
KnockKnockClient
class implements the client program that speaks to the KnockKnockServer
. KnockKnockClient
is based on the EchoClient
program in the previous section, Reading from and Writing to a Socket and should be somewhat familiar to you. But we'll go over the program anyway and look at what's happening in the client in the context of what's going on in the server.
When you start the client program, the server should already be running and listening to the port, waiting for a client to request a connection. So, the first thing the client program does is to open a socket that is connected to the server running on the specified host name and port:
When creating its socket, the
KnockKnockClient
example uses the host name of the first command-line argument, the name of the computer on your network that is running the server program KnockKnockServer
.
Training charts can be a great tool to use so that children can visually see their progress, as they are potty training. They can see how well they are doing and add their own potty training stickers to the chart as well. They can actively be involved in the process of potty training. Mickey mouse potty chart printable. Potty Training Chart - Reward Sticker Chart - Girls Theme - Marks Behavior Progress – Motivational Toilet Training for Toddlers and Children – Great for Boys and for Girls (Girls Theme) 4.3 out of 5 stars 32. Big Boy Underpants Fran Manushkin. 4.7 out of 5 stars 72. What others are saying 'How to potty train a 2 year old little girl potty sticker chart ideas,potty time sticker chart potty training at 18 months,potty training clipart potty training movies.' Pull-Ups® Potty Training Sticker Charts Print out a Sticker Chart with your trainee. Hang the chart on the wall in the bathroom at your child’s eye level, and let your them pick a small sticker to put on the chart every time they're successful on the potty.
The
KnockKnockClient
example uses the second command-line argument as the port number when creating its socket. This is a remote port number—the number of a port on the server computer—and is the port to which KnockKnockServer
is listening. For example, the following command runs the KnockKnockClient
example with knockknockserver.example.com
as the name of the computer that is running the server program KnockKnockServer
and 4444 as the remote port number:
The client's socket is bound to any available local port—a port on the client computer. Remember that the server gets a new socket as well. If you run the
KnockKnockClient
example with the command-line arguments in the previous example, then this socket is bound to local port number 4444 on the computer from which you ran the KnockKnockClient
example. The server's socket and the client's socket are connected.
Next comes the
while
loop that implements the communication between the client and the server. The server speaks first, so the client must listen first. The client does this by reading from the input stream attached to the socket. If the server does speak, it says 'Bye.' and the client exits the loop. Otherwise, the client displays the text to the standard output and then reads the response from the user, who types into the standard input. After the user types a carriage return, the client sends the text to the server through the output stream attached to the socket.
The communication ends when the server asks if the client wishes to hear another joke, the client says no, and the server says 'Bye.'
The client automatically closes its input and output streams and the socket because they were created in the
try
-with-resources statement.
Running the Programs
You must start the server program first. To do this, run the server program using the Java interpreter, just as you would any other Java application. Specify as a command-line argument the port number on which the server program listens:
Next, run the client program. Note that you can run the client on any computer on your network; it does not have to run on the same computer as the server. Specify as command-line arguments the host name and the port number of the computer running the
KnockKnockServer
server program:
If you are too quick, you might start the client before the server has a chance to initialize itself and begin listening on the port. If this happens, you will see a stack trace from the client. If this happens, just restart the client.
If you try to start a second client while the first client is connected to the server, the second client just hangs. The next section, Supporting Multiple Clients, talks about supporting multiple clients.
When you successfully get a connection between the client and server, you will see the following text displayed on your screen:
Now, you must respond with:
The client echoes what you type and sends the text to the server. The server responds with the first line of one of the many Knock Knock jokes in its repertoire. Now your screen should contain this (the text you typed is in bold):
Now, you respond with:
Again, the client echoes what you type and sends the text to the server. The server responds with the punch line. Now your screen should contain this:
If you want to hear another joke, type y; if not, type n. If you type y, the server begins again with 'Knock! Knock!' If you type n, the server says 'Bye.' thus causing both the client and the server to exit.
If at any point you make a typing mistake, the
KnockKnockServer
object catches it and the server responds with a message similar to this:
The server then starts the joke over again:
Note that the
KnockKnockProtocol
object is particular about spelling and punctuation but not about capitalization.
Supporting Multiple Clients
To keep the
KnockKnockServer
example simple, we designed it to listen for and handle a single connection request. However, multiple client requests can come into the same port and, consequently, into the same ServerSocket
. Client connection requests are queued at the port, so the server must accept the connections sequentially. However, the server can service them simultaneously through the use of threads—one thread per each client connection.
The basic flow of logic in such a server is this:
Socket Program For One Way Communication
The thread reads from and writes to the client connection as necessary.
Try This:
Modify the
KnockKnockServer
so that it can service multiple clients at the same time. Two classes compose our solution:KKMultiServer
and KKMultiServerThread
. KKMultiServer
loops forever, listening for client connection requests on a ServerSocket
. When a request comes in, KKMultiServer
accepts the connection, creates a new KKMultiServerThread
object to process it, hands it the socket returned from accept, and starts the thread. Then the server goes back to listening for connection requests. The KKMultiServerThread
object communicates to the client by reading from and writing to the socket. Run the new Knock Knock server KKMultiServer
and then run several clients in succession.
Home > Articles > Programming > Java
␡
- A Server Socket in Java
< BackPage 4 of 11Next >
This chapter is from the book
Just Java 2, 5th Edition
This chapter is from the book
This chapter is from the book
A Server Socket in Java
This section shows a simple example of creating a server socket to listen for incoming requests. We could write the server side of a simple NTP server, but let's try something a little more ambitious. It should be fairly clear at this point that HTTP is just another of the many protocols that use sockets to run over the Internet.
A web browser is a client program that sends requests through a socket to the HTTP port on a server and displays the data that the server sends back. A basic web browser can be written in a couple of hundred lines of code if you have a GUI component that renders HTML, which Java does.
A web server is a server program that waits for incoming requests on the HTTP port and acts on those to send the contents of local files back to the requestor. It can be implemented in just a few dozen lines of code.
Security of Network Programs—A Cautionary Tale!
Be very careful when you start developing networked programs on your computer. Before you try it at work, check if there is a company policy about network use. You can get fired for doing the wrong thing!
The problem is that any server sockets you create may be visible more widely than you intended. If you are running this at home, and you are not using a firewall, your server socket will be visible to the entire net. That's like leaving the front door of your home wide open.
When I was developing the HTTP server in Java for this chapter, I left it running on my PC to test it. Someone's automated port scanner script soon noticed my server, made an unauthorized connection to it, and issued this HTTP command:
This is an attempt to break out of the scripts directory, run a shell, and do a 'dir' to see what's on my system. Crackers will try to add their own backdoor on your computer where you'll never find it. Then they can use your system whenever it's on the net (they love cable modems) for such things as distributed denial of service attacks. My server was logging client requests, but not fulfilling them, so the nimrod was out of luck. But be careful out there; people are actively looking for systems to break into.
The example here is part of the code for a web server. This is the code that opens a server socket on the http port, port 80, and listens for requests from web browsers. We echo the requests, but don't act on them.
The code is split into two classes to better show what's happening. The first class is the main program. It instantiates a server socket on port 80 (use port 1080 if you're on a Unix system without root access). The code then does an accept() on the server socket, waiting for client connections to come in. When one does come in, the program creates a new object to deal with that one connection and invokes its getRequest() method.
There are only two new lines of code in this server program. This line:
and this line:
The first line instantiates a server socket on the given port (httpd is an int with the value 80). The second line does an accept() on this server socket. It will block or wait here until some client somewhere on the net opens a connection to the same port, like this:
At that point, the accept() method is able to complete, and it returns a new instance of a socket to the server. The rest of this conversation will be conducted over the new socket, thus freeing up the original socket to do another accept() and wait for another client. At the client end, the socket doesn't appear to change.
In a real server, the code will loop around and accept another connection. We'll get to that. Here is the second half of the code: the OneConnection class that the main program uses to do the work for a single client request.
The constructor keeps a copy of the socket that leads back to the client and opens the input and output streams. Sockets always do I/O on bytes, not Unicode chars. HTTP is a line-oriented protocol. We push a BufferedReader onto the input stream so we can use the convenient readLine() method. DataInputStream has one of those too, but it is deprecated.
If you're using a binary protocol, do everything with streams, not readers/writers. We wrap a DataOutputStream on the output side of the socket. We don't write anything in this version of the program, but we will soon develop it and start writing.
Socket Protocols
The getRequest() method reads successive lines from the socket and echoes them on the server. How does it know when to stop reading lines? This is one of the tricky things with sockets—they cannot tell the difference between 'end of input' and 'there is more input, but it is delayed coming through the network.'
To cope with this inability to know when it's done, socket protocols use one of three approaches:
-
have the client precede each message by a number giving the length of the following message. Or use some other indication to end transmission, such as sending a blank line.
-
have the client close its output stream, using sock.shutDownOutput(). That causes the next read at the server end to return -1.
-
set a timeout on the socket, using sock.setSoTimeout(int ms). With this set to a non-zero amount, a read call on the input stream will block for only this amount of time. Then it will break out of it by throwing a java.net.SocketTimeoutException, but leaving the socket still valid for further use.
The third approach, using timeouts, is the least reliable because timeouts are always too long (wasting time) or too short (missing input). HTTP uses a mixture of approaches one and two.
Running the HTTP Server Program
Compile the code and then run the program. Make sure you run it on a computer that is not already running a web-server, otherwise it will find that it cannot claim port 80. If all is well, the program will print out:
then it will block, waiting for an incoming request on the port. This is exactly what a webserver does: opens port 80 and waits for incoming socket connections from clients.
Loopback Address
<Anchor1>Every computer system on the Internet has a unique IP address consisting of four groups of digits separated by periods like this: 204.156.141.229
They are currently revising and increasing the IP address specification so that there will be enough new IP addresses to give one to every conceivable embedded processor on earth, and a few nearby friendly planets. These version 6 addresses look like: 1080:0:0:0:8:800:200C:417A
One special version 4 IP address is: 127.0.0.1. This is the 'loopback' address used in testing and debugging. If a computer sends a packet to this address, it is routed to itself, without actually leaving the system. Thus, this special address can be used to run Internet software even if you are not connected to the Internet. Set your system up so that the Internet services it will be requesting are all at the loopback address. Make sure your system is actually running the demons corresponding to the services you want to use.
The hostname for the loopback address is 'localhost,' if you are requesting services by name rather than IP address. On any system, you should be able to enter the command 'ping localhost' and have it echo a reply from the loopback IP address. If you can't do this, it indicates that your TCP/IP stack is not set up properly.
Here's the interesting part. You can make that connection using any web browser! Just start up your browser and direct it to the computer where you are running the Java program. You can run your browser on a different system altogether, and give it the name of the computer running the Java program.Or, if you are running everything on one computer, the name will be 'localhost,' and the URL will be something like:
The rest of the URL doesn't matter since our server program doesn't (yet) do anything with the incoming request. You will see the Java server print out the message that a socket connection has been made ('got a socket'), and then print the HTTP text it receives on the socket from the browser!
These strings are HTTP headers. They are created by the browser to tell the server what file it has asked for, and they provide information about what kinds of format the browser can accept back.
Write A Socket Program For Echo/ping/talk Commands In Java 1
A couple more points to note here. First, almost all servers uses threads. That way, they can serve the client and at the same time accept further requests. We will shortly show the code to do this. Second, these dozen or so lines of server code are at the heart of every webserver. If you add a couple of routines to read whatever file the browser asks for and write it into the socket, you have written a webserver. Let's do it.
The ServerSocket API is:
The accept() method listens for a client trying to make a connection and accepts it. It creates a fresh socket for the server end of the connection, leaving the server socket free to do more accepts.
The bind() method is used to connect an existing socket to a particular IP address and port. You would use this when you want to use channels instead of streams for socket I/O; there's an example at the end of the chapter.
• – Thousands of free titles in text and HTML file formats. Novel religi best seller pdf. • – A page of links to some recent books from living authors available free online. • – In Adobe’s Free eBooks area, you can download, unlock, and read electronic books on your personal computer or reading device.
The other methods should be clear from their names. There are other methods in the API, but these are the main ones you will use.
Debugging Sockets
The little HTTPServer program we just saw can be used to help debug some server socket problems. You can see exactly what headers the browser sends you for different HTML requests. It works for other protocols too. If you make the code listen on another port, you can look at the incoming stream there.
Standing on the Corner, Watching All the Packets Go By
The server program, shown on the previous pages, will echo all the input that is sent to one socket. This is similar to the way that the FBI's controversial Carnivore program works.
Carnivore was created so that the FBI could do the online equivalent of phone tapping. It works at the more fundamental level of individual packets rather than sockets, but the principle is the same.
Carnivore is basically a packet sniffer that can be installed at an ISP and directed to copy packets that meet certain criteria (to or from a given IP address, for example). In this way, Carnivore can give the FBI a copy of all the email, all the web site visits, all the telnet sessions for a particular target over the course of a month or more. A court order is needed to authorize each use of Carnivore.
The FBI made a PR error by giving the program such an aggressive name. Law enforcement needs access to these tools to track down online fraud, network disruption, and other crimes. But they would have done themselves a favor by calling the software something calmer like 'Old Packet Collector.'
Another debugging technique uses the telnet program to look at incoming text to a client socket. Telnet's actual purpose is to open a command shell on a remote computer. The lines you type are sent over the socket connection, and the responses sent back the same way. However, you can tell telnet to use any port. The stream that it receives on that port will be displayed in the telnet window, and the things you type will be sent through the socket back to the server. The characters you type will be sent to the other end, but not echoed however.
Telnet is just a quick and dirty debugging technique to help you see what's going on. Figure 17–4 uses telnet to see what an NTP server is sending back. Most servers will close a socket as soon as they have given you the requested information, hence the 'connection lost' pop-up window. There is also a 'keep-alive' option to a socket that requests the connection be retained for expected use in the very near future. This is useful for HTTP.
Figure 17–4 Debugging with Telnet.
These days you should avoid the use of telnet and ftp for their main purpose, as they send passwords 'in the clear' to the remote socket. They are thus vulnerable to packet-sniffing by crackers at routers. Use SSH, the secure shell, instead. There is a Java implementation of SSH on the CD that comes with this book.
Using Netstat
Another useful tool for seeing what is going on with your network connection is netstat. It is available on Windows and Unix. Run netstat like this:
This shows all the current IP connections, the local socket, the remote socket, and the state. Netstat lets you see if you can at least make a connection to a remote system.
The '-?' option to netstat will give you a message about other options.
Finally, there's a very helpful website at straylight.cso.niu.edu. You can use one of their webpages (specifically, straylight.cso.niu.edu/cgi-bin/test-cgi.cmd) to see what is happening with your HTML pages. If you specify that web page as the 'Action' value for an HTML form, when you press the 'submit' button, the script will echo back to you everything that your form sent across. If this site goes off the net, try doing a websearch for 'CGI test forms'. Using an echo script makes it easy to see what is going on, and hence what you need to correct.
Getting the HTTP Command
Let's add a few lines of code (in bold) to our server to extract the HTTP 'GET' command that says what file the browser is looking for. We will develop this example by extending the OneConnection class. That way, we will add just the new code in the child class, and use the existing methods from the parent. The code in the new child class is:
The getRequest() method now looks at incoming HTTP headers to find the one containing a GET command. When it finds it, it writes an acknowledgement back to the browser (the '200 OK' line), and extracts the filename from the GET header. The filename is the return value of the method.
The main program will need to construct the OneConnection_A object and then call its getRequest() method. From here it is a small step to actually get that file and write it into the socket.
Never Use println() with Sockets!
The println() method is defined to output the platform specific line separator. This will be 'n' on Unix, 'r' on Macs, and 'rn' on Windows.
However, lots of TCP/IP protocols are line based, and the line is defined to end with carriage return line feed 'rn', or just line feed 'n'. So if you're on a Mac, the println method won't output something that a socket server recognizes as a complete end of line sequence.
The Mac client will do a println, which sends a 'r', and then wait for a response from the server. The server will get the 'r' and wait for a 'n' to complete the end of line sequence. Result: deadlock! Each end is waiting for something from the other. See Apple Tech Note 1157 for more on this:
developer.apple.com/technotes/tn/tn1157.html
The solution is to never use println with remote protocols on any platform. Always use explicit 'rn' characters when writing to a socket.
Here's a new class that is a child of OneConnection_A; it adds a method to get the file of the given name and write it into the socket. Since it knows how big the file is, it might as well generate the HTTP header that gives that information.
The main program will need to construct the OneConnection_B object and then add a call to its send file method. Now that our server has the ability to return files we need to build in some security. The first few lines of the method prepend the string '/tmp/' onto the filename. The code also checks that the filename does not contain the string '.' to enter a parent directory. These two limitations together ensure that the server will only return files from your tmp directory.
The 'Content-Length' and 'Content-Type' are two standard HTTP headers that help the browser deal with what you send it. The blank line tells the browser that is the end of the headers and the text that follows should be displayed.
At this point you should try compiling the code, placing a test html file in the tmp directory, and then starting the server. Browse the URL localhost/tmp/exam_ple.html and check that the browser displays the file correctly.
We have completed a basic webserver. That's quite an accomplishment! The next section looks at client side sockets again, in particular how to use a socket to pull information from a web page. It then shows the same task done by a URLConnection. We then describe the class that represents IP addresses and finish the chapter by making the web server multithreaded.
Related Resources
- Book $35.99
- Book $55.99
Write A Socket Program For Echo/ping/talk Commands In Java 10
- Book $43.99