Here I provide a set of examples on using sockets
with the Java
. I recommend using
Eclipse as developer environment for Java. Matter of fact, this folder contains an Eclipse project named sockets
which can directly be imported into Eclipse.
The following examples are included in this folder.
The simple TCP Client and TCP Server examples do nothing spectacular.
The client sends one byte with value 1
over a TCP connection to the server (which listens at port 9999 of the local host) and terminates.
The server accepts 5 incoming connections, prints the received byte, and then terminates.
This is exactly the same example as TCPClient/TCPServer
above, except that it uses Java 1.7's try-with-resource
statement to handle the sockets. It is therefore both more compact and robust.
The simple UDP Client and UDP Server examples do nothing spectacular, actually, basically the same as the TCP client/server (except that they use port 9998 and the UDP instead of the TCP protocol).
The client sends one byte with value 1
in an UDP package to the server and terminates.
The server accepts 5 incoming packages, prints the received byte, and then terminates.
This is exactly the same example as UDPClient/UDPServer
above, except that it uses Java 1.7's try-with-resource
statement to handle the sockets. It is therefore both more compact and robust.
This example contains of a client which reads characters from stdin
and sends them over TCP to a server listening at port 9999 of the local host. Once return
is pressed, it will close its connection. The server part will read raw byte
s from an incoming connection, cast them to char
s and print them. This leads to the issue of encoding: If characters are not in the normal, Western, 7 bit range of ASCII, garbage will result.
As we learn in the lesson, the memory layout of even primitive data types and structures may be different from machine to machine. This example shows how we can send and receive different instances of (primitive) data types over a TCP connection with Java.
We therefore use Java's DataInputStream
/DataOutputStream
API to realize a small calculator client-server application. The client sends an operation name (add
or sub
) and two 64 bit long integers to the server. The server computes the result and sends it back. The application uses TCP port 9996 and the client connects to the local host.
This program is also a very simple client/server application which shows the basic concept of remote procedure calls (RPC): A client sends the identifier of a method it wishes to be executed, along with its parameters, (marshalled) to an RPC server. The server reads the method it, unmarshalls the parameters, invokes the method, and sends back the results. Of course, this is done by fancy frameworks and all, but the basic idea is this simple.
As we learn in the lesson, the memory layout of even primitive data types and structures may be different from machine to machine. This example shows how we can send and receive different instances of (primitive) data types via a UDP package with Java. It works basically the same as the TCP example above, just with UDP and port 9997.
We use Java's DataInputStream
/DataOutputStream
API to realize a small calculator client-server application. The client sends an operation name (add
or sub
) and two 64 bit long integers to the server. The server computes the result and sends it back. The application uses TCP port 9996 and the client connects to the local host.
A minimum HTTP Server, i.e., a small web server. It accepts HTTP reqeuests from normal web browsers and resolves the path part of the requests URLs against the file system. If it can load the requested file, it will send it as text as answer. Otherwise, it will send an error page (in HTML) containing the exception encountered when trying to load the file. This server just sequentially processes client after client at port 9995.
A minimum HTTP clients, i.e., a program that behaves similar to a small web browser (at least, from the web server's perspective). It opens a connection to a web server, sends a HTTP request, and prints the answer. Both in "normal" Java and using Java 1.7's try-with-resource
statement.
In the above MinHTTPServer
example, the server processes one client after the other. Everytime, it loads the requested file from the disk and sends it to the client. However, while it is waiting to load a file from disk, it has nothing to do. It could accept another client connection and already read its header. Actually, we could process as many client connections in parallel as our machine allows.
This example here behaves exactly like the MinHTTPServer
, except that it creates a new thread which runs in parallel. Each thread then does exactly the same as the old MinHTTPServer
's connection processing code.
The above example MinHTTPClientMultiThread
can achieve some good parallelism to process multiple requests. However, it is also wasteful. Threads are operating system resources and we create one for each connection and afterwards discard it. Additionally, if many connections come in at once, we may create many threads and try to read many files at once, which may slow down our server or cause it to crash.
In this example here, we therefore use a thread pool. A thread pool is a set of threads, let's say 10. Whenever a connection comes in, we submit it as job to the thread pool. The first thread who is not busy doing something else catches this job and processes it in the same way as in the MinHTTPClientMultiThread
example. While doing so, it is busy. Afterwards, it may process the next job. This means we can process 10 connections in parallel. No threads are discarded and no additional threads are created.
A simple sequential HTTP server which sends back the client's requests as HTML files. It is single-threaded. Clients are accepted from port 9995
and everything they send is stored in a buffer. This buffer is then sent back inside <pre>...</pre>
tags with line breaks (<br/>
) added.
A client/server application which tries to approximate the value of Pi. The clients therefore sample a couple of numbers randomly from the unit square and count how many of them fall into the unit circle. They send both, the number of sampled points and the number of those in the unit circle, to the server. The server manages two such counters as well and updates them with data received from the clients. It can use these numbers to estimate Pi. Many clients can work in parallel and send their numbers to the server. This should increase speed significantly.
Different from the normal client/server structure, the client here does the work. This is somewhat similar to the processing model of MPI.
Here you can find a C implementation for computing Pi in a similar fashion by using the Message Passing Interface.