Java Dev
Java Dev
Java Dev
Java Networking
1. Java Networking
2. Java Networking: Socket
3. Java Networking: ServerSocket
4. Java Networking: UDP DatagramSocket
5. Java Networking: URL + URLConnection
6. Java Networking: JarURLConnection
7. Java Networking: InetAddress
8. Java Networking: Protocol Design
Jakob Jenkov
Last update: 2014-06-23
If you are designing a client-server system you may also have to design a communication protocol between the client
and the server. Of course, sometimes this protocol is already have been decided for you, e.g. HTTP, XML-RPC (XML
over HTTP), or SOAP (also XML over HTTP). But once in a while the protocol decision is open, so let's look at a few
issued you may want to think about when designing your client - server protocol:
Send Request
Receive Response
When a computer (client or server) sends data to another computer over the internet it takes some time from the time
the data is sent, to the data is received at the other end. This is the time it takes the data to travel over the internet. This
time is called latency.
The more roundtrips you have in your protocol, the slower the protocol becomes, especially if latency is high. The
HTTP protocol consists of only a single request and a single response to perform its service. A single roundtrip in
other words. The SMTP protocol on the other hand, consists of several roundtrips between the client and the server
before an email is sent.
The only reason to break your protocol up into multiple roundtrips is, if you have a large amount of data to send from
the client to the server. You have two options in this case:
Sending the header in a separate roundtrip (the first) can be smart if the server can do some initial pre-validation of e.g.
header information. If that header information is invalid, sending the large body of data would have been a waste
anyways.
If the network connection fails while you are transfering a large amount of data, you may have to resend all that data
from scratch. By breaking the data up into smaller chunks you only have to resend the chunks from the chunk where
the network connection failed and onwards. The successfully transfered chunks do not have be resent.
1. Send the length in bytes of the request in the beginning of the request.
2. Send an end-of-request marker after the request data.
HTTP uses the first mechanism. In one of the request headers the "Content-Length" is sent. This header tells how
many bytes after the headers that belongs to the request.
The advantage of this model is that you don't have the overhead of the end-of-request marker. Nor do you have to
encode the body of the data to avoid the data looking like the end-of-request marker.
The disadvantage of the first method is that the sender must know how many bytes are transfered before the data is
transfered. If the data is generated dynamically you will first have to buffer all the data before sending it, to count the
number of bytes.
By using an end-of-request marker you don't have to know how many bytes you are sending. You just need to send an
end-of-request marker at the end of the data. You do, however, have to make sure that the data sent does not contain
any data that can be mistaken for the end-of-request marker. Here one way to do that:
Lets say the end-of-request marker is the byte value 255. Of course the data can contain the value 255 too. So, for
each byte in the data that contains the value 255 you add an extra byte, also with the value 255. The end-of-request
marker is changed from the byte value 255 to 255 followed by the value 0. Here are the encodings summarized:
The sequence 255, 0 can never occur in the data, since you are changing all 255's to 255,255. And, a 255,255,0 will
not be mistaken for a 255,0. The first 255's will be interpreted together, and the last 0 by itself.
Penetrating Firewalls
Most firewalls block all other traffic than the HTTP protocol. Therefore it can be a good idea to layer your protocol
ontop of HTTP, like XML-RPC, SOAP and REST does.
To layer your protocol ontop of HTTP you send your data forth and back between client and server inside HTTP
requests and responses. Remember, an HTTP request and response can contain more than just text or HTML. You
can send binary data inthere too.
The only thing that can be a little weird by layering your request ontop of the HTTP protocol is that an HTTP request
must contain a "Host" header field. If you are designing a P2P protocol ontop of HTTP, your peers most likely won't be
running multiple "Hosts". This required header field is in that situation an unnecessary overhead (but a small one).
Tweet
Jakob Jenkov
All Trails
Trail TOC
Page TOC
Previous
Next
Tutorials About RSS
Tech and Media Labs
Java Networking
1. Java Networking
2. Java Networking: Socket
3. Java Networking: ServerSocket
4. Java Networking: UDP DatagramSocket
5. Java Networking: URL + URLConnection
6. Java Networking: JarURLConnection
7. Java Networking: InetAddress
8. Java Networking: Protocol Design
Jakob Jenkov
Last update: 2014-06-25
In order to implement a Java server that listens for incoming connections from clients via TCP/IP, you need to use a
java.net.ServerSocket . In case you prefer to use Java NIO instead of Java Networking (standard API), then
you can also use a ServerSocketChannel instead of the java.net.ServerSocket.
Creating a ServerSocket
Here is a simple code example that creates a ServerSocket that listens on port 9000:
Additionally, incoming connections can only be accepted while the thread running the server has called accept().
All the time the thread is executing outside of this method no clients can connect. Therefore the "accepting" thread
normally passes incoming connections (Socket's) on to a pool of worker threads, who then communicate with the
client. See the tutorial trail Java Multithreaded Servers for more information on multithreaded server design.
socket.close();
serverSocket.close();
Tweet
Jakob Jenkov
All Trails
Trail TOC
Page TOC
Previous
Next
Tutorials About RSS
Tech and Media Labs
Java Networking
1. Java Networking
2. Java Networking: Socket
3. Java Networking: ServerSocket
4. Java Networking: UDP DatagramSocket
5. Java Networking: URL + URLConnection
6. Java Networking: JarURLConnection
7. Java Networking: InetAddress
8. Java Networking: Protocol Design
Jakob Jenkov
Last update: 2014-06-25
In order to connect to a server over the internet (via TCP/IP) in Java, you need to create a java.net.Socket and
connect it to the server. Alternatively you can use a Java NIO SocketChannel, in case you prefer to use Java NIO.
Creating a Socket
This code example connects to the server with IP address 78.46.84.171 on port 80. That server happens to be my
web server (www.jenkov.com), and port 80 is the web servers port.
You can also use a domain name instead of an IP address, like this:
Writing to a Socket
To write to a Java Socket you must obtain its OutputStream. Here is how that is done:
Socket socket = new Socket("jenkov.com", 80);
OutputStream out = socket.getOutputStream();
out.write("some data".getBytes());
out.flush();
out.close();
socket.close();
Don't forget to call flush() when you really, really want the data sent across the internet to the server. The
underlying TCP/IP implementation in your OS may buffer the data and send it in larger chunks to fit with with the size
of TCP/IP packets.
in.close();
socket.close();
Keep in mind that you cannot always just read from the Socket's InputStream until it returns -1, as you can when
reading a file. The reason is that -1 is only returned when the server closes the connection. But a server may not
always close the connection. Perhaps you want to send multiple requests over the same connection. In that case it
would be pretty stupid to close the connection.
Instead you must know how many bytes to read from the Socket's InputStream. This can be done by either the
server telling how many bytes it is sending, or by looking for a special end-of-data character.
Closing a Socket
When you are done using a Java Socket you must close it to close the connection to the server. This is done by
calling the Socket.close() method, like this:
socket.close();
Tweet
Jakob Jenkov
All Trails
Trail TOC
Tutorials About RSS
Tech and Media Labs
Java Networking
1. Java Networking
2. Java Networking: Socket
3. Java Networking: ServerSocket
4. Java Networking: UDP DatagramSocket
5. Java Networking: URL + URLConnection
6. Java Networking: JarURLConnection
7. Java Networking: InetAddress
8. Java Networking: Protocol Design
Jakob Jenkov
Last update: 2014-06-23
DatagramSocket's are Java's mechanism for network communication via UDP instead of TCP. UDP is still layered
ontop of IP. You can use Java's DatagramSocket both for sending and receiving UPD datagrams.
With UDP you just send packets of data (datagrams) to some IP address on the network. You have no guarantee that
the data will arrive. You also have no guarantee about the order which UDP packets arrive in at the receiver. This
means that UDP has less protocol overhead (no stream integrity checking) than TCP.
UDP is appropriate for data transfers where it doesn't matter if a packet is lost in transition. For instance, imagine a
transfer of a live TV-signal over the internet. You want the signal to arrive at the clients as close to live as possible.
Therefore, if a frame or two are lost, you don't really care. You don't want the live broadcast to be delayed just to make
sure all frames are shown at the client. You'd rather skip the missed frames, and move directly to the newest frames at
all times.
This could also be the case with a surveillance camera broadcasting over the internet. Who cares what happened in
the past, when you are trying to monitor the present. You don't want to end up being 30 seconds behind reality, just
because you want to show all frames to the person monitoring the camera. It is a bit different with the storage of the
camera recordings. You may not want to lose a single frame when recording the images from the camera to disk. You
may rather want a little delay, than not have those frames to go back and examine, if something important occurs.
Sending Data via a DatagramSocket
To send data via Java's DatagramSocket you must first create a DatagramPacket. Here is how that is done:
The byte buffer (the byte array) is the data that is to be sent in the UDP datagram. The length of the above buffer,
65508 bytes, is the maximum amount of data you can send in a single UDP packet.
The length given to the DatagramPacket constructor is the length of the data in the buffer to send. All data in the
buffer after that amount of data is ignored.
The InetAddress instance contains the address of the node (e.g. server) to send the UDP packet to. The
InetAddress class represents an IP address (Internet Address). The getByName() method returns an
InetAddress instance with the IP address matching the given host name.
The port parameter is the UDP port the server to receiver the data is listeing on. UDP and TCP ports are not the same.
A computer can have different processes listening on e.g. port 80 in UDP and in TCP at the same time.
To send the DatagramPacket you must create a DatagramSocket targeted at sending data. Here is how that is
done:
datagramSocket.send(packet);
datagramSocket.receive(packet);
Notice how the DatagramSocket is instantiated with the parameter value 80 passed to its constructor. This
parameter is the UDP port the DatagramSocket is to receive UDP packets on. As mentioned earlier, TCP and UDP
ports are not the same, and thus do not overlap. You can have two different processes listening on both TCP and UDP
port 80, without any conflict.
Second, a byte buffer and a DatagramPacket is created. Notice how the DatagramPacket has no information
about the node to send data to, as it does when creating a DatagramPacket for sending data. This is because we
are going to use the DatagramPacket for receiving data, not sending it. Thus no destination address is needed.
Finally the DatagramSocket's receive() method is called. This method blocks until a DatagramPacket is
received.
The data received is located in the DatagramPacket's byte buffer. This buffer can be obtained by calling:
byte[] buffer = packet.getData();
How much data was received in the buffer is up to you to find out. The protocol you are using should specify either
how much data is sent per UDP packet, or specify an end-of-data marker you can look for instead.
A real server program would probably call the receive() method in a loop, and pass all received
DatagramPacket's to a pool of worker threads, just like a TCP server does with incoming connections (see Java
Multithreaded Servers for more details).
Tweet
Jakob Jenkov
All Trails
Trail TOC
Page TOC
Previous
Next
Tutorials About RSS
Tech and Media Labs
Java Networking
1. Java Networking
2. Java Networking: Socket
3. Java Networking: ServerSocket
4. Java Networking: UDP DatagramSocket
5. Java Networking: URL + URLConnection
6. Java Networking: JarURLConnection
7. Java Networking: InetAddress
8. Java Networking: Protocol Design
Jakob Jenkov
Last update: 2014-06-23
The InetAddress is Java's representation of an IP address. Instances of this class are used together with UDP
DatagramSockets and normal Socket's and ServerSocket's.
And here is how to get the InetAddress matching a String representation of an IP address:
And, here is how to obtain the IP address of the localhost (the computer the program is running on):
Tweet
Jakob Jenkov
All Trails
Trail TOC
Page TOC
Previous
Next
Tutorials About RSS
Tech and Media Labs
Java Networking
1. Java Networking
2. Java Networking: Socket
3. Java Networking: ServerSocket
4. Java Networking: UDP DatagramSocket
5. Java Networking: URL + URLConnection
6. Java Networking: JarURLConnection
7. Java Networking: InetAddress
8. Java Networking: Protocol Design
Java Networking
Jakob Jenkov
Last update: 2014-06-25
Java has a reasonably easy-to-use builtin networking API which makes it easy to communicate via TCP/IP sockets or
UDP sockets over the internet. TCP is typically used more often than UDP, but both options are explained in this
tutorial.
There are three other tutorials here at tutorials.jenkov.com that are relevant to this Java networking tutorial. These
are:
1. Java IO Tutorial
2. Java NIO Tutorial
3. Java Multithreaded Servers Tutorial
Even though the Java Networking APIs enable you to open and close network connections via sockets, all
communication happens via the Java IO classes InputStream and OutputStream.
Alternatively you can use the networking classes in the Java NIO API. These classes are similar to the classes found
in the Java Networking API, except the Java NIO API can work in non-blocking mode. Non-blocking mode may give a
performance boost in some situations.
Open Connection
Send Request
Receive Response
Close Connection
A client may send more than one request through an open connection. In fact, a client can send as much data as the
server is ready to receive. The server can also close the connection if it wants to.
If you want to start a server that listens for incoming connections from clients on some TCP port, you have to use a
Java ServerSocket. When a client connects via a client socket to a server's ServerSocket, a Socket is assigned on
the server to that connection. The client and server now communicates Socket-to-Socket.
Because there is no guarantee of data delivery, the UDP protocol has less protocol overhead.
There are several situations in which the connectionless UDP model is preferable over TCP. These are covered in
more detail in the text on Java's UDP DatagramSocket's.
Tweet
Jakob Jenkov
All Trails
Trail TOC
Page TOC
Previous
Tutorials About RSS
Tech and Media Labs
Java Networking
1. Java Networking
2. Java Networking: Socket
3. Java Networking: ServerSocket
4. Java Networking: UDP DatagramSocket
5. Java Networking: URL + URLConnection
6. Java Networking: JarURLConnection
7. Java Networking: InetAddress
8. Java Networking: Protocol Design
Java's JarURLConnection class is used to connect to a Java Jar file. Once connected you can obtain information
about the contents of the Jar file. Here is a simple example:
...
Tweet
Jakob Jenkov
Copyright Jenkov Aps
All Trails
Trail TOC
Page TOC
Previous
Next
Tutorials About RSS
Tech and Media Labs
Java Networking
1. Java Networking
2. Java Networking: Socket
3. Java Networking: ServerSocket
4. Java Networking: UDP DatagramSocket
5. Java Networking: URL + URLConnection
6. Java Networking: JarURLConnection
7. Java Networking: InetAddress
8. Java Networking: Protocol Design
Jakob Jenkov
Last update: 2014-06-23
The java.net package contains two interesting classes: The URL class and the URLConnection class. These
classes can be used to create client connections to web servers (HTTP servers). Here is a simple code example:
Once you have set called setDoOutput(true) you can open the URLConnection's OutputStream like this:
OutputStream output = urlConnection.getOutputStream();
Using this OutputStream you can write any data you want in the body of the HTTP request. Remember to URL
encode it (search Google for an explanation of URL encoding).
Remember to close the OutputStream when you are done writing data to it.
Here is an example of how to open a file in the local file system using the URL class:
Notice how the only difference from accessing a file on a web server via HTTP is the the URL:
"file:/c:/data/test.txt".
Tweet
Jakob Jenkov
All Trails
Trail TOC
Page TOC
Previous
Next