Download as pdf or txt
Download as pdf or txt
You are on page 1of 17

1.

2 Java sockets API 2

ServerSocket this is used by the “receiver” of connections, this is often a server


program (although the idea of server is more about the application than the way con-
nections are established). A ServerSocket is used to advertise a service, it is used by
the program to inform the operating system that it will deal with incoming connection
Java Network Programming requests for a specified port, The receiver program waits for incoming connections by
calling the accept function in the server socket,
Socket this is a “connection” it is an object containing streams that convey bytes be-
October 2010 tween programs. The connecting program will create a new Socket and give it an
address and a port, this will cause the operating system to contact the remote system to
see if the connection can be established. If the connection is accepted the socket can
be used to send bytes to and receive bytes from the other program. If the connection is
1 Sockets successful the waiting receiver returns from the accept function with a new connected
socket.
1.1 Socket streams and datagrams
The following picture 1 shows this. I’m sorry it’s not a very good diagram but it might
There are 2 forms of transport level network interprocess connection with the TCP/IP help. The sequence of events in figure 1 is:
family of protocols:
time server client
UDP a connectionless single message, or datagram. There is no guarantee of delivery of
a UDP datagram (although in practice nearly all packets get through). 1 ss=new ServerSocket(port)

TCP a bi-directional stream connection. The stream is “reliable” which means the un- 2 conn=ss.accept()
derlying network level requires acknowledgement of each packet sent in the stream, if
any are lost then they are retransmitted transparently to the process using the stream. 3 conn=new Socket(IP,port)
wakes up
A TCP connection is in some ways similar to a telephone call, the link stays open until
either end “hangs-up”, even if nothing is being said. This is the program to program 4 ins=conn.getInputStream() outs=conn.getOutputStream()
communication used by most network applications.
5 out.write(b)
6 ins.read(b)
1.2 Java sockets API
A TCP connection on the internet is a bi-directional link between two running programs Figure 1: Java socket use
(not computers). The connection is just a stream of characters (in Java bytes) wrtten by
one program and read by another. It is the standard service made available by operating
systems to application programs, the interface is known as the BSD socket interface. Most
1. A “receiver” program (server) creates a server socket and gives it a port number, it will
internet applications are programs that use TCP connections, they send their own protocol
receive incoming connections to that port:
messages to each other through the TCP connections.
ServerSocket ss=new ServerSocket(port);
No matter whether the network application is client-server or peer-to-peer whenever
one program must contact another there is asymmetry in the use of TCP connections One
2. it then waits for an incoming connection request by calling:
will wait to accept a connection and another must connect to it.
conn = ss.accept();
Sockets are available in Java through the java.net.* package. There are two main
classes: Socket for connected sockets, and ServerSocket for listening sockets. The two nothing happens for a bit. . .
different types of socket reflect the asymmetry of connections.
3. in a distant galaxy far far away a “client” program creates a socket:
Socket conn = new Socket(IP,port)
3 Java Network Programming 2.1 ReceiveBytesTCP01.java 4

1 import java.io.*;
where IP is the IP address or name of the receiver’s computer and port is the number 2 import java.net.*;
used when the ServerSocket was created. This is a connection request. 3
If the connection request succeeds (this involves the operating systems communicat- 4 public class ReceiveBytesTCP01 {
ing) then the client returns with a connected socket which it can use. The receiver also 5 public static void main(String args[]) throws Exception {
returns from the accept function and it has a newly generated connected socket of its 6 int port = Integer.parseInt(args[0]);
own, 7 ServerSocket serverSock=new ServerSocket(port);
8
4. they are now connected. However Java does not allow direct reading and writing of 9 Socket conn = serverSock.accept();
the socket (unlike Unix system calls), instead it remembers it has “streams” it uses for 10 InputStream ins = conn.getInputStream();
file I/O so it requires that the programs extract Streams from their sockets. In this 11 byte buf[] = new byte[1024];
example, the receiver will only read the connection and the client will only write so 12
one gets an InputStream and the other an OutputStream. The receiver does: 13 while (true) {
InputStream ins=conn.getInputStream(); 14 int rc = ins.read(buf,0,1024);
15 if(rc <= 0) break;
and the client does: 16 System.out.write(buf,0,rc);
OutputStream outs=conn.getOutputStream(); 17 }
18 conn.close();
5. the client writes (in this case), 20 }
6. and the server reads (in this case). 21 }

Since these streams are exactly the same as the streams returned when you open files Other things to note:
they can be used in the same way with read and write. Except reading and writeing
these streams will receive and send data to the other program to which the socket is • the port number is supplied as a string from the command line. It must be converted to
connected. an integer on line 6 before it can be used to open the “listening” ServerSocket on line
7. The accept() on line 9 causes the program to wait for an incoming connection,
• if and when a connection is made to this program, it wakes up and returns a new “con-
2 Very simple example nected” Socket which can be used for reading and writing to and from the connecting
program,
This section includes two very trivial programs, one of which, ReceiveBytesTCP01.java
creates a server socket and awaits a connection, the other program SendBytesTCP01.java • in Java it isn’t possible to read and write a socket directly since all reading and writing
makes a connection. The sender sends everything from its standard input over the net- is through streams, it is necessary to get an InputStream and or an OutputStream
work, the receiver (once it has a connection) reads everything from the network connec- from the socket. Since this program is going to read everything sent to it over the
tion and writes it all to its standard output. network, in order to read a socket it only needs to getInputStream() on line 10,
• the program then loops reading from the socket (on line 14) and writing it to the stan-
2.1 ReceiveBytesTCP01.java
dard output (on line 16). It only stops when the read on line 14 returns 0 or less, this
ReceiveBytesTCP0.java creates a server socket and then waits for connections with means the other end has closed the connection—it has “hung-up”. This is checked on
accept. When it gets a connection it reads everything sent to it and writes it to the line 15 when break; is executed causing the program it terminate the loop and start
standard output System.out (usually the console). When the connection finishes (the executing statements after the loop, in this case line 18 onwards.
remote user died?) the read returns a byte count of zero and the loop stops.
• Look at an example of simple file I/O to remind yourself how read and write work.
5 Java Network Programming 2.3 Running the programs 6

2.2 SendBytesTCP01.java 2.3 Running the programs


Now the “connecting” program that will contact the “receiver” and (in this case) send it Assume that the two programs using keyboard input and console output, ie. there is no
all the characters typed at its console. It is called SendBytesTCP01.java. It requires two standard input or output redirection. The program ReceiveBytesTCP01.java must be run
command line arguments to use to make the connection: the IP address or name of the first because to must be ready to accept before the other program SendBytesTCP01.java
receiver’s computer and the port. can execute new Socket() and connect to it (remember network communication is al-
ways asymmetric). First, on machine 147.197.236.240:
1 import java.io.*;
2 import java.net.*; $ java ReceiveBytesTCP01 2222
3
it should wait until it gets a connection. Then on another system the command to run the
4 public class SendBytesTCP01 {
sender, followed by text typed into the running program, is entered:
5 public static void main(String args[]) throws Exception {
6 String host = args[0]; $ java SendBytesTCP02 147.197.236.240 2222
7 int port = Integer.parseInt(args[1]); are you there?
8 Socket conn=new Socket(host, port);
9 OutputStream outs=conn.getOutputStream(); then the message “are you there?” will be sent to 147.197.236.240 port 2222 which
10 byte buf[] = new byte[1024]; will arrive at the receiver and be printed on the console.
11
12 while (true) { 2.4 Simple exercises
13 int rc = System.in.read(buf,0,1024);
14 if(rc <= 0) break; 1. Make ReceiveBytesTCP01.java check that it has the right number of command line
15 outs.write(buf,0,rc); arguments, for the receiver one argument. If a program hasn’t got the right number
16 } it should print an error message and exit. Look at the previous file reading program
17 conn.close(); Copy3.java that checks the number of command line arguments, or look a couple of
18 } pages ahead at SendBytesTCP02.java which checks its arguments aswell as handling
19 } exceptions. Compile it, run it and test it.

Notes: 2. The program ReceiveBytesTCP01.java creates a ServerSocket, accepts one con-


nection, repeatedly reads from the connection writing all it gets, when that connection
• the two arguments are the host name or IP number to connect to, and the port number closes, it finishes. Many servers, when they have finished processing one connec-
it is using. Creating a Socket connection needs the first argument as a String, which tion, will loop round and accept another connection. Add a new “outer” loop so this
it is from args[0] but the second argument the port must be an integer so the String program will repeat accepting a connection and reading it all. Think carefully where
args[1] must be converted to an integer on line 7, the loop starts and ends, in orger to to another accept it doesn’t need to create a new
ServerSocket it can reuse the existing one. Also there is no stopping test for the outer
• the command on line 8 that creates a Socket, it attempts to make a connection which loop, most servers are written to run forever (or at least until the machine is turned off
will wake up the accept in the receiving program and create a connected socket. It or somebody types “control-c” at the console). Compile and test the program, you can
can fail in different ways that will cause exceptions (more later. . . ) test it by running the sender, stopping it, running it a second time and you should not
• this program only needs to write to the socket so it just uses needs an OutputStream need to re-run the receiver, if your change has worked the receiver will still be running.
for the socket, it gets it on line 9, 3. Add a line to ReceiveBytesTCP01.java that prints out on the standard output the ad-
• it then reads from the standard input and writes what it gets to the socket. This pro- dress of the “client” sender that has connected to it everytime it accepts a new connec-
gram finishes if the read from the standard input System.in (usually the keyboard) tion. There is a method that can be used with connected sockets (not ServerSockets)
returns 0 bytes, which means “end-of-file”, this can be done at the keyboard by typing that gives the IP address of the system at the other end of the connection:
“control-d”.
conn.getInetAddress()
7 Java Network Programming 2.6 Why can’t this program be changed to send and receive? 8

if conn is the connected Socket. getInetAddress returns an object of type InetAddress, Suppose that the program is busy doing other tasks and doesn’t execute read very
you can look it up in the Java API reference pages but you don’t need to because. . . An often but the other end of the connection is sending a lot of bytes. What will happen?
InetAddress will automatically be converted to a String if you use it in a con- Firstly all operating systems have per-connection buffering and will hold some bytes
text where a String is needed. So if you append an InetAddress to a string using until the program is ready to read them. If the buffers in the operating system network
“+” it will be converted. So you can put it as part of the output string argument to drivers are becoming full special TCP messages will be sent to the sender system
System.out.println for example. Compile it and test it. asking it to slow down, this will result in subsequent write calls in the sender blocking
to wait for the receiver to read something and make some space in the buffers.
2.5 More about read and write Once again, like with keyboard input, just because no bytes are available it doesn’t
mean input is finished, the sender program might just be a bit slow. A TCP socket
The read method behaves slightly differently with different sources of input. So given connection stays open indefinitely until one end “closes” the connection. So the only
the same read: time 0 will be returned to a read is when the other end executes close().
rc = ins.read(buffer,0,1024);
2.6 Why can’t this program be changed to send and receive?
there will some differences with the following three sources of input:
Well it can. . . but not simply. If the program is going to send then it must try to read from
from a file when reading is from a disc file there will be a delay because reading from a the keyboard and this will cause it to “block” (wait), however it must also be prepared
disc is thousands of times slower that main memory or the CPU. But the delay is small to read incoming messages from the network connection, once again it must block. How
and relatively predictable when compared with the next two. can it wait in two places at the same time? It has a single “thread” of control, if it waits
Each time the read is executed it will get the next 1024 bytes, it is as if it has a pointer anywhere nothing else can happen. Section 6 on threads explains one way of solving this
moving through the file. Every successful read except the last should get 1024 bytes problem.
and therefore will assign 1024 to rc. The last successful read will get the remaining
bytes, so if a file contains 2,500 bytes, the first two reads will each get 1024 bytes
but the third will get 452 bytes. If read is executed a fourth time it will get nothing, 3 Catching an exception
there are no more bytes to read so it will return 0 and assign it to rc—this indicates
“end-of-file”. This version has been altered to catch the UnknownHostException exception. This is
important because the most likely way for the connection to fail is that: the address is
from the keyboard when standard input is read without any redirection read will almost wrong, the port is wrong, or the receiver isn’t actually running. In all these cases the
always have to wait a variable amount of time for the user to type stuff in. connection will fail to be established, this is detected and reported when the sender (client)
It will read one line (so long as it is less than 1024 characters long), the actual number executes:
of bytes read and put in buffer will be returned to rc. Socket conn = new Socket(IP,port)
It is hard to know when the end of input is reached because the user might have finished
or just be thinking for longer than usual. So a way of indicating “end-of-file” is for the exception thrown can be caught and the use can be informed. There were also other
the user to type: “control-d” on Linux or “control-z” on Windows. This will cause the exceptions that were ignored in the simpler versions the commonest is IOException
read to read no characters and return 0 which will be assigned to rc in this example. which occurs if there are any network communication problems.
An exception in a program is the failure of some operation to finish correctly. This
from a network connection like the keyboard input and unlike the file it is possible there could be a runtime error such as a failure to read or write correctly. catch the exception
are no bytes available, or there are less than 1024. If there are no bytes available read by surrounding any statements that could cause an exception with:
will wait, if some bytes arrive they will be read immediately even if there are fewer
than 1024, the number actually read into buffer will be returned as the result and try { statements-that-might-cause-exception} catch(...) {...}
assigned to rc. However it is possible that a lot of bytes have arrived since the last The catch clauses “match” each different exception and are followed by any number of
read, in which case read will get as many as it can, ie. 1024, and then read the rest statements, in this case an error message followed by exit.
on subsequent reads.
9 Java Network Programming 10

import java.io.*; This is a minimal version with no the checking of arguments and exception handling.
import java.net.*; An extended version is shown afterwards.

public class SendBytesTCP02 { import java.io.*;


public static void main(String args[]) { import java.net.*;
if(args.length != 2 ) {
System.err.println("need host name or IP and port"); public class HTTPGet0 {
System.exit(1); public static void main(String args[]) throws Exception {
} int port = Integer.parseInt(args[2]);
String host = args[0]; Socket socket = new Socket(args[0], port);
int port = Integer.parseInt(args[1]); OutputStream outs = socket.getOutputStream();
try { InputStream ins = socket.getInputStream();
Socket conn=new Socket(host, port); byte buffer[] = new byte[8192];
OutputStream outs=conn.getOutputStream();
byte buf[] = new byte[1024];
String request = "GET " + args[1] + " HTTP/1.1\r\n"
while (true) { + "Host: " + args[0] + "\r\n"
int rc = System.in.read(buf,0,1024); + "Connection: Close\r\n\r\n";
if(rc <= 0) break;
outs.write(buf,0,rc); outs.write(request.getBytes());
}
conn.close(); while (true) {
} catch(UnknownHostException e) { int rc = ins.read(buffer,0,8192);
System.err.println("Can’t find host: " + args[0]); if(rc<=0) break;
System.exit(1); System.out.write(buffer,0,rc);
} catch(IOException e) { }
System.err.println("Connection failed or IO error"); outs.close(); socket.close();
System.exit(1); }
} }
} The program is in the file HTTPGet0.java. This program will act as a dumb client. It will
} send a request to a remote http server. Note that this program needs three command line
arguments, the remote host address, the port and the file (page) to retrieve preceded with
There are probably many other improvements that can be made to these programs but a “/”. To compile and run the program:
there’s not much point because they are not very useful.
$ javac HTTPGet0.java
$ java HTTPGet0 tink.stca.herts.ac.uk /tiny.html 80
4 A client example HTTP/1.1 200 OK
Date: Sun, 16 Mar 2003 23:32:10 GMT
The following example just illustrates a simple client program, it takes as arguments: an Server: Apache/1.3.26 (Unix) Debian GNU/Linux
internet address and a WWW page name, it builds an HTTP request and sends it to a Last-Modified: Wed, 08 May 2002 23:45:10 GMT
remote web server, it then reads and prints everything the server sends back, this will Accept-Ranges: bytes
include all the HTTP protocol response lines aswell as the file (page). There is no need Content-Length: 492
Content-Type: text/html; charset=iso-8859-1
for a matching server to be written because there are lots out there already for it to talk to.
Connection: close
11 Java Network Programming 4.1 A fuller version 12

4.1 A fuller version


<H1> Example Page </H1>
This is the first paragraph, it is terminated by a This is a slightly more deluxe version of the program. It has better checking of command
... line arguments. However the basic functionality is very similar
import java.io.*;
which will get tiny.html from tink.stca.herts.ac.uk. Notes:
import java.net.*;
• first attempt to connect to the server by creating a new socket using the remote system
name (or number) and the port: public class HTTPGet1 {
public static void main(String[] args) throws Exception {
socket = new Socket(args[0], port); final int BUFSIZ=8192;
int port = 0;
if this fails an exception will be raised but not caught so the program will fail, if( args.length == 3 ) {
port = Integer.parseInt(args[2]);
• now extract the input and output streams: } else if( args.length == 2) {
port = 80;
toServer = socket.getOutputStream();
} else {
fromServer = socket.getInputStream(); System.err.println("Usage: HTTPGet1 server file [port]");
System.exit(1);
• now build a full HTTP file request as a string in request, although read and write }
work with byte arrays it is easier to build a request using a Java String, byte buffer[] = new byte[BUFSIZ];

• and send it to the server: Socket socket = new Socket(args[0], port);


OutputStream toServer = socket.getOutputStream();
toServer.write(request.getBytes());
InputStream fromServer = socket.getInputStream();
but the String request must now be changed to bytes because write requires an String request =
array of bytes, getBytes will get such an array out of the String request. Now the "GET " + args[1] + " HTTP/1.1\r\n"
message is sent to the server, + "Host: " + args[0] + "\r\n"
+ "Connection: Close\r\n\r\n";
• if the server exists and if it reads the request, and if it thinks our request well-formed
and if it has such a file then it will send it down the same connected socket. We must toServer.write(request.getBytes());
read the socket to get the returning file:
while (true) {
rc = fromServer.read(buffer,0,8192); int rc = fromServer.read(buffer,0,BUFSIZ);
if(rc<=0) break;
read puts the characters read into a pre-allocated array of bytes, here called buffer. System.err.write(buffer,0,rc);
The return result, put in rc, is the number of characters actually put in buffer. The }
client cannot know how big the file is (if it’s an MPEG video it might be megabytes), toServer.close();
so it reads in “chunks” of 8k, that is why there is a loop, that reads and then prints to socket.close();
System.out, }
}
• when we can read no more (rc <= 0 is true) we close everything and finish.
The program is in the file HTTPGet1.java. Notes:
• first it checks the command line arguments:
– if a port number is provided it will use it, ie. if the number of arguments is three
args.length==3
13 Java Network Programming 4.2 A programming example: HTTPGet3.java 14

– if there is no port number provided the program will use 80, ie. if the number of HTTP/1.1 200 OK
arguments is threetwo args.length==2 Date: Sun, 24 Oct 2010 23:07:34 GMT
Server: Apache/2.2.16 (Debian)
– otherwise if there are not at least two arguments it’s an error,
Last-Modified: Fri, 01 Oct 2010 13:50:22 GMT
• it also has a named constant as the buffer size. The length of the array used as a buffer Accept-Ranges: bytes
Content-Length: 134
is used in more than one place so the advantage of a named constant is that it helps
Connection: close
ensure consistency,
Content-Type: text/html
• apart from that it is similar to HTTPGet0.java
<h1> Tiny Example Page </h1>
<p> This is a tiny HTML file, it contains just
4.2 A programming example: HTTPGet3.java one paragraph surrounded by open and closing tags. </p>

This section shows how to develop an improvement to the HTTPGet0.java program. It will start with the sequence of bytes:
is an example of how to use streams and to solve a network programming problem but,
perhaps more importantly, it is also an example of simple Java programming, showing H T T P / 1 . 1 2 0 0 O K CR LF D a t e : . . .
how to use arrays, strings and functions. to end the first line. And the byte sequence before and after the blank line is:

4.2.1 The requirement . . . t e x t / h t m l CR LF CR LF < h 1 > T i . . .

The goal is to change the program to: So the first “CR LF” ends the Content-Type: text/html” and the second “CR LF” is
the blank line—there were no other bytes.
• save the file that is returned from the server, in the first version it is just displayed on But how does the program detect the linefeed byte that ends the line? The current ver-
the console. The file will be saved with the name of the resource, so if the command sion of the program, HTTPGet0.java repeatedly reads blocks of 8192 bytes, the carriage
is: return and line feed could be anywhere, they might even be split between two blocks of
bytes. There are various possible ways of dealing with the problem. One way might be to
java HTTPGet3 tink.stca.herts.ac.uk /tiny.html 80
read a block and then search through it looking for carriage return and linefeed. But that
the program should remove the “/” and save what is returned with name tiny.html, way is quite complicated. Another possibility is to write a function readLine that will
read one line from the TCP socket InputStream every time it is called; not only will that
• it will only try to save the file if the first response line from the server is “HTTP/1.1 find the first line to check for “200” but when it reads a line with nothing in it it will have
200 OK”, in other cases it will print an error, found the blank line. The function readLine will:
• also it must only save the correct file contents, that means that it must not save any • read one line byte by byte and store all the bytes, when it finds carriage return and line
of the option lines. The HTTP protocol requires that every response has a blank line feed it will create a String and return it,
after the option lines and before the file contents. Therefore the program must skip the
option lines and the blank line and only start saving the bytes after the blank line. • it will not include the carriage return and linefeed in the string so an empty, blank line
will have a zero length, ie it contains nothing,
4.2.2 The problem: skipping the header lines • it will leave the TCP socket InputStream in a state where the next byte will be the
How do you get the first line to look for “200” and then how do you know where the one immediately after the carriage return and linefeed.
response option lines end and the file contents start? First the program must detect the
end of the first line and then it must detect the blank line. In network text messages lines The main program will have to:
usually end with two bytes: carriage return and then linefeed, written in Java as “\r” and • call the readLine function to get the first line, save it,
“\n”. So the response:
• then skip all the option lines by reading them one by one and stopping when one of
the lines has a zero length (it’s the blank line),
15 Java Network Programming 4.2 A programming example: HTTPGet3.java 16

• then the program checks if the first line contained “200” if it did it will create a file line. If the byte is the end of line marker, a linefeed, written in Java as “\n” then the loop
and read the rest of the TCP socket InputStream bytes into the file. The reading of stops because executing break: causes it to jump out of the loop to the first statement
the rest of the stream will be done, as before, in blocks, not line by line, because: following the loop:
1
1. it’s more efficient, the program will loop 8192 of the number of times and issue only 7 if(line[count] == ’\n’) break;
1
8192 the number of read library calls, and
note that line[count] is the last byte read. If the byte is not linefeed then the next
2. very often downloaded files will not be readable ASCII characters, they will be statement in the loop will be executed:
image files, movies or executable programs, in which case there is no guarantee
that they will have any bytes that are carriage return or line feed, 8 if(line[count] != ’\r’) { count++; }

• if it’s not “200” it will print a message and stop. it counts the byte stored if it wasn’t the “carriage return” character, written in Java as “\r”.
Obviously it must increment the count for the bytes stored so the next byte will be stored
4.2.3 The design of the readLine function in the next element of the array. But why not increment if it’s “\r”? The linefeed marks
the end of line but it is usually preceded by a carriage return, therefore the loop only stops
The function readLine will take an InputStream as an argument and return a String when a linefeed is read and the carriage return must be ignored, skipped, or got rid of
built from the bytes read from the stream up to the end of line character(s). somehow. If a carriage return byte is read the variable count is not incremented and on
the next iteration of the loop the read statement will overwrite it with the next byte—that
2 static String readLine(InputStream ins) throws Exception {
effectively ignores it.
3 byte line[] = new byte[256];
4 int count=0;
5 while(true) { 4.2.4 Dry run showing the operation of the read loop
6 int rc = ins.read(line,count,1); When readLine is called the array is created, it is empty, and the variable count is set to
7 if(line[count] == ’\n’) break; 0:
8 if(line[count] != ’\r’) { count++; }
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 255
9 }
10 return new String(line,0,count);
11 } count = 0 input stream HTTP/1.1 200 OKCRLF Date...

It has static in front because it is called by another static function main. Don’t worry
the read reads the first byte “H” and stores it in line at offset count which is 0, it then
about this, if you are writing methods that will be called in objects they will be just the
checks if line[count] is linefeed, no, so it continues and checks if it’s carriage return,
same but without static in front.
no so it increments count to 1:
The server response will arrive as a stream:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 255
input stream HTTP/1.1 200 OKCR LF Date... H
C L
count = 1 input stream TTP/1.1 200 OK R F Date...
The function has a local array line which will get the bytes of the next line, one by one,
into consecutive locations. The variable count will be used to index the array aswell as
the next iteration of the loop reads “T”, the next byte from the TCP socket connection
count the bytes in the line. The loop will read one byte on each iteration and store it into
stream, and stores it in line[1] because 1 is the current value of count. It’s not “\n” or
the correct position in line:
“\r” so count is incremented to 2:
6 int rc = ins.read(line,count,1); 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 255
H T
read takes as arguments: an array, then the offset in the array where the bytes read will
be stored, then lastly a count of the number of bytes to read. So in this case if count count = 2 input stream TP/1.1 200 OK C L
R F Date...
is incremented every time the bytes will be stored in consecutive positions of the array
17 Java Network Programming 4.2 A programming example: HTTPGet3.java 18

the next byte, another “T” is dealt with similarly: 35 if(! (firstLine.startsWith("HTTP") && firstLine.contains("200"))){
36 // not 200 OK response
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 255
37 System.err.println("Not 200 OK");
H T T
38 } else { // OK save the file
C L
count = 3 input stream P/1.1 200 OK R F Date...
this is probably a bit more than is needed but it first checks the first line is a server response
line, ie. it starts with “HTTP” and then checks it contains “200”. It uses the two String
and this continues until the sequence of bytes: “HTTP/1.1 200 OK” has been read and
methods:
stored in line:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 255 • s.startsWith(p) which gives true if s starts with p,
H T T P / 1 . 1 2 0 0 O K • s.contains(p) which gives true if s has the substring p anywhere in it.
C L
count = 15 input stream R F Date... In order to create a new file to store the downloaded document it takes the resource
name that was the second argument on the command line, args[1], and strips off the the
on the next cycle of the loop “\r” is read in and stored in line[15]” (15 is the current leading “/”:
value of count) but it isn’t counted, count is still 15. Next time round the loop linefeed,
the end of line marker, “\n” is read and the loop stops. 39 String fname=args[1].substring(1);
At the end of the loop the array line holds “HTTP/1.1 200 OK” in the first 15 ele- 40 OutputStream ofile = new FileOutputStream(fname);
ments, that is: 0–14 and count is 15. The statement: 41
42 while (true) {
10 return new String(line,0,count); 43 int rc = fromServer.read(buffer,0,2048);
44 if(rc<=0) break;
turns the array of bytes into a Java String and returns it. The array line contains 15
45 ofile.write(buffer,0,rc);
bytes and the value of count is 15 so new String(line,0,count) uses the 15 bytes
46 }
from line[0] to line[14] to make the string, the linefeed that’s in line[15] is ignored
47 ofile.close();
and not used.
There is a String method s.substring(n) that takes on argument “n” and returns a new
4.2.5 Using the function readLine string that contains all the characters from the string s from index position “n” to the end.
So s.substring(1) returns a new string identical to s but without the first character.
Now the function is complete it must be used by the rest of the program to read and save Remember almost everything in Java starts at index position “0”, characters in strings
the first line from the server and then skip all the other option lines up to and including the aswell as elements of arrays, so position 1 is the second character.
blank line. After that the program will open a new file and write all the remaining bytes
from the InputStream into the file. The code:
4.2.6 The whole program HTTPGet3.java
29 String firstLine = readLine(fromServer); 1 public class HTTPGet3 {
30 while(true) { 2 static String readLine(InputStream ins) throws Exception {
31 String line = readLine(fromServer); 3 byte line[] = new byte[256];
32 if(line.length() == 0) break; 4 int count=0;
33 } 5 while(true) {
6 int rc = ins.read(line,count,1);
will do that. It calls readLine once to get the first line, then loops until the String line 7 if(line[count] == ’\n’) break;
has length zero meaning it is a blank line, then it stops. 8 if(line[count] != ’\r’) { count++; }
The next job the program must do is to check if the first line is an “OK” server response 9 }
and output an error if not: 10 return new String(line,0,count);
11 }
19 Java Network Programming 20

12 public static void main(String[] args) throws Exception { client and immediately sends whatever it read back again. When the connection from a
13 System.setProperty( "java.net.preferIPv4Stack", "true" ); client is closed (a rc==0 returned from read) the server loops to accept the next connec-
14 int port = 80; tion from another client. The client makes a connection and then loops each time: reading
15 byte buffer[] = new byte[2048]; from the user, writing this text to the server, reading the server’s response (which should
16 be the same) and then printing it. The server:
17 Socket socket = new Socket(args[0], port);
18 OutputStream toServer = socket.getOutputStream(); import java.io.*;
19 InputStream fromServer = socket.getInputStream(); import java.net.*;
20 String request =
21 "GET " + args[1] + " HTTP/1.1\r\n"
public class EchoServer0 {
22 + "Host: " + args[0] + "\r\n"
23 + "Connection: Close\r\n\r\n";
public static void main(String args[]) throws Exception {
24 System.setProperty( "java.net.preferIPv4Stack", "true" );
25 toServer.write(request.getBytes()); int echoPort = Integer.parseInt(args[0]);
26 byte buffer[] = new byte[4096];
27 // now read server response and skip option lines ServerSocket serverSock = new ServerSocket(echoPort);
28 // followed by file Socket connSock;
29 String firstLine = readLine(fromServer);
30 while(true) { while(true) {
31 String line = readLine(fromServer); connSock = serverSock.accept();
32 if(line.length() == 0) break; OutputStream outs = connSock.getOutputStream();
33 }
InputStream ins = connSock.getInputStream();
34 // all header lines read, check first to see if OK
35 if(! (firstLine.startsWith("HTTP") && firstLine.contains("200")) ) {
36 // not 200 OK response while (true) {
37 System.err.println("Not 200 OK"); int rc = ins.read(buffer,0,4096);
38 } else { // OK save the file if(rc <= 0) break;
39 String fname=args[1].substring(1); outs.write(buffer,0,rc);
40 OutputStream ofile = new FileOutputStream(fname); }
41 outs.close(); ins.close(); connSock.close();
42 while (true) { }
43 int rc = fromServer.read(buffer,0,2048); }
44 if(rc<=0) break; }
45 ofile.write(buffer,0,rc);
46 } The program is in the file EchoServer0.java.
47 ofile.close();
48 } • This is a very cut-down program, there is no error checking or exception handling,
49 toServer.close(); socket.close();
50 } • notice that the server loops forever:
51 }
while(true) {
...
5 Client server example echo nearly all servers are like this, deal with one request and loop to “accept” the next,
This example consists of a server and a client. They do very little except show how a • this is a server so it must create a ServerSocket bound to a port number. The port
stream connection is set up. The server awaits (accept) a connection, reads from the number to use is provided as an argument. It then waits by calling accept,
21 Java Network Programming 22

• this network program reads and writes bytes into a buffer not single characters or lines. the line “hello” is read from the user, sent to the server returned by it, read from the
However it is worth noting how much will be read, consider: socket by the client and then printed “echo: hello”. Unlike the server the client only
deals with one session, it only has one loop to read and echo, when the user finishes (by
rc = ins.read(buffer,0,4096);
typing control-d “^d” on Unix) the loop finishes and the program finishes.
with a network connection it will read all the bytes available into buffer starting at The “echo service” isn’t obviously very useful, however it is a real internet standard
offset 0 up to a maximum of 4096. If there are no bytes it will block, if there are more protocol, it’s main use is for testing. Also it is a useful example for introducing simple
than 4096 bytes it will read just 4096 this time. The number of bytes read is returned networking concepts. BUT notice about this version of the server EchoServer0.java:
and assigned to rc,
• there are two while loops, one nested in the other,
• it then loops reading from the client and writing back again. When it gets rc==0 from
read (which would be end of file for a file) it means the client closed the connection. • the outer one awaits and accepts a new client connection

Now the client, once again this is a cutdown, non-error checking one: • the inner one repeatedly reads and writes messages from the current client
public class EchoClient0 { • while it is dealing with one client it is waiting for messages it CANNOT also be waiting
public static void main(String[] args)throws Exception{ for other new client connections
System.setProperty( "java.net.preferIPv4Stack", "true" );
Socket sock=new Socket(args[0],Integer.parseInt(args[1])); • only when the current client closes the connection will the server break out of the loop
OutputStream outs=sock.getOutputStream(); and go rounf the outer loop to await a new client connection
InputStream ins=sock.getInputStream(); • it is a sequential server, it deals with clients one at a time
byte buffer[]=new byte[4096];

while (true) { 6 Threads


int rc = System.in.read(buffer,0,4096); // read from user
if(rc <= 0) break; Threads allow parts of a program to execute in parallel. With two threads it allows one
outs.write(buffer,0,rc); // write to net thread to wait for one event and the second thread to wait for another event, this means
rc = ins.read(buffer,0,4096); // read from net a program can watch for more than one event at the same time, why is this useful in
if(rc <= 0) break; networking?
System.out.write("got: ".getBytes()); // write to user A thread is a sequence of statement execution through a program, it is like a “virtual
System.out.write(buffer,0,rc); // write to user processor” with a program counter and a stack of saved returned addresses. Every pro-
} gram has at least one thread, it is the execution path through the program. It is possible to
outs.close(); ins.close(); sock.close(); have more than one thread within the same program being run. That means that different
} bits of the program are being executed in parallel, in other words different bits of code
} are being executed at the same time (at least logically although not absolutely simultane-
ously unless the computer has more than one processor). The Java virtual machine and
The program is in the file EchoClient0.java. To test the client and server programs:
compile them both, run the server with an arbitrary port number: the underlying operating system switch between all the threads and allow each to exe-
cute, switching to another one when the running one “blocks” (ie. doesn’t want to keep
tink$ java EchoServer0 3333 executing because it is waiting for some event).
it should just wait and go nothing, it is not waiting for keyboard input, it is waiting for
network messages. Then in another xterm run the client: 6.1 The need for multiple threads
plink$ java EchoClient0 tink 3333 There are many reasons for using multiple threads but the principle underlying reason is
hello
that the program needs to wait for more than thing at a time. There will be three examples
echo: hello
considered:
...
23 Java Network Programming 6.2 Threads in Java 24

1. The first example is a server that needs to deal with more than one client transaction at class MyThread extends Thread {
a time, maybe an improved version of the EchoServer that will deal with many clients ...
at once, public MyThread(...) { ... }
public void run() {
2. the second example is the need for a program to send to and receive the network at the ...
same time, }
3. and the final one is the problem of receiving from the network and awaiting GUI ...
commands in one program, }
...
...
6.1.1 A server dealing with multiple clients
MyThread mythrd = new MyThread(...);
Consider the simple (stupid?) echo server EchoServer0.java, it creates a ServerSocket mythrd.start();
and awaits a connection from a client, it then enters a loop reading everything from the ...
client and sending it back. While it is looping dealing with one client it cannot be exe- Note:
cuting accept and getting other connections. Does this matter? Well for the echo server
probably not BUT it is the same problem for other servers, all web servers work in the • every thread must provide public void run(), this is the code that will be executed
same way, suppose that a client has a slow internet connection, the web server must read when the thread starts,
their request and write the required file (maybe a large MP3) to the slow connection, all • when a thread is created with new it doesn’t start immediately, the thread is a class
this time no other browser requests can be accepted. type so the constructor is executed in order to initialise the object but run doesn’t start
The solution is to create a separate thread for each client request, each thread then
reads and writes its own socket connection to its single client. When one thread “blocks” • to start a thread the code that created it must then call start, that causes the Java
to wait for input from its client it doesn’t affect the other threads. virtual machine to start the run() function in parallel.

6.1.2 Reading and writing asynchronously 6.2.2 By implementing Runnable

Consider the first simple pair of programs SendBytesTCP0.java and ReceiveBytesTCP0.java, Another way to create a thread to execute a separate body of code is to write a class
why shouldn’t they be combined into a single version that could enable a proper dialogue that implements the interface Runnable, which really means it must provide a public
with another such program (a bit like a very simple messenger program)? Do do this there void run() function. This in itself is not a thread, a plain Thread must then be created
would need to be two threads because there would be a need to “wait” in two places: one separately and given an object of the Runnable to run. Here is the skeletal code:
thread would wait for user input and then write it to the network, and the other thread class MyRun implements Runnable {
would be waiting for bytes arriving from the network and writing them to the console. ...
public MyRun(...) { ... }
6.2 Threads in Java public void run() {
...
Most languages and operating systems provide threads, unfortunately each does it in dif- }
ferent way. Java makes it even worse by providing two ways to do it (why does Java ...
always make life so hard by being so complicated and having a thousand different ways }
to do something???). ...
...
6.2.1 By inheritance MyRun runObj = new MyRun(...);
Thread thrd = new Thread(runObj);
One way is to write a new class that “inherits” from, or extends, the class Thread, in
thrd.start();
other words write your own thread class.
...
25 Java Network Programming 6.2 Threads in Java 26

Note: thread2.start();
}
• any class implementing Runnable must provide public void run(), this is the code }
that will be executed when the thread starts,
The program is in the file Threads1.java. When the threads are started they execute their
• a runnable object is created, in the example above it is runObj, it is not a thread but it run routine for ever repeatedly printing out their message. If this is compiled and run it
has a run function that could be used by a thread, can produce almost any output sequences depending on how the threads are scheduled,
which means how they are allocated a share of the CPU time. Here is part of one sequence:
• a Thread is created, in this case thrd, it is a plain, standard, un-extended thread.
It is given the runnable object as an argument to its constructor, this means that the bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
separately executable thread will execute the run function in runObj, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
• but runObj cannot be scheduled for execution (even though it provides) the instruc- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
tions, it is the thread that must be started: thrd.start(). aaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb

Even with a multiprocessor computer the output will be affect by how Java buffers the
6.2.3 What is the difference? messages it writes. One thread may give a lot of output to the operating system which
Very little. Maybe the use of inheritance (“extending”) is a bit simpler. On the other hand will be printed before the output of another thread.
It is possible to force the scheduling of the threads to change and to be more inter-
because a class can only extend at most one other class you might implement Runnable
leaved by causing a thread to “sleep” briefly after every print statement:
so the class can extend some other class.
class Loopy extends Thread {
6.2.4 A two thread program (not doing networking) String message;

Here is a very simple example that : Loopy(String mess) { message = mess; }

• declares one thread class: Loopy, public void run() {


for(int i=0; i<1000; i++) {
• the main program then creates two thread objects try { Thread.sleep(1); } catch(Exception e) {}
System.out.print(message); System.out.flush();
• it then starts each of the thread objects
}
class Loopy extends Thread { }
String message; }
public class Threads2 {
Loopy(String mess) { message = mess; } public static void main(String[] args) {
Thread thread1 = new Loopy("a");
Thread thread2 = new Loopy("b");
public void run() {
for(int i=0; i<1000; i++) { thread1.start();
System.out.print(message); System.out.flush(); thread2.start();
}
}
} }
} The statement to cause the thread to sleep is: Thread.sleep(1), the 1 is the number of
public class Threads1 {
milliseconds it will sleep for. Unfortunately it is made more complicated because it is
public static void main(String[] args) {
possible (though unlikely) for sleep() to cause an exception so it is necessary to enclose
Thread thread1 = new Loopy("a");
Thread thread2 = new Loopy("b"); the sleep with a very minimal exception handler:
thread1.start(); try { Thread.sleep(1); } catch(Exception e) {}
27 Java Network Programming 6.4 Sending and receiving revisited 28

it doesn’t do much but it does allow the program to compile. Here is some output from System.out.println("Usage: EchoServer port");
this version: System.exit(1);
}
ababababababababababababababababababababababababababab try {
ababababababababababababababababababababababababababab ServerSocket serverSock=new ServerSocket(Integer.parseInt(args[0]));
ababababababababababababababababababababababababababab while(true) {
ababababababababababababababababababababababababababab Socket connSock = serverSock.accept();
ServiceThread serve = new ServiceThread(connSock);
6.3 A concurrent echo server serve.start();
}
If a server has to deal with a long transaction for a client, involving lots of waits for } catch (IOException e) {
reading and writing files and sockets, it will be unable to accept new requests. One System.err.println("EchoServer: error on socket");
simple solution is to change the server so that after the accept it creates a “child” thread. System.exit(1);
This new thread uses the new “connected” socket to service the clients request, and then }
dies. The parent thread goes back to accept to await another connection. This is called a }
concurrent server. }

import java.io.*; The program is in the file EchoServerConc0.java.


import java.net.*;
• After the accept a new thread is created and given the connected socket connSock,
class ServiceThread extends Thread {
Socket conn=null; • the new thread is now started, and runs in parallel with other threads and main,

public ServiceThread(Socket c) { conn = c; } • the parent (main) thread loops to do accept again,
• the child thread runs and handles the client transaction, when this is finished it reaches
public void run() {
the end and terminates.
final int bufsiz=16384;
byte buff[] = new byte[bufsiz];
try { 6.4 Sending and receiving revisited
OutputStream out = conn.getOutputStream();
InputStream in = conn.getInputStream(); We can use threads to combine the first example programs SendBytesTCP0.java and
ReceiveBytesTCP0.java into a program that can both read from the keyboard and send
while (true) { to a remote program, and also read from the remote program and print on the console.
int rc = in.read(buff,0,bufsiz);
if(rc<=0) break;
6.4.1 The problem
out.write(buff,0,rc);
} This first attempt at a solution only adds one thread because all Java programs have one
out.close(); conn.close(); already. The new thread will read from the network blocking on every read, and then
} catch (IOException e) { write to the keyboard:
System.err.println("EchoServer: error reading socket");
System.exit(1); while (true) {
} int rc=ins.read(buf,0,1024);
} if(rc<=0) break;
} System.out.write(buf,0,rc);
public class EchoServerConc0 {
}
public static void main(String args[]) {
if( args.length != 1 ) {
29 Java Network Programming 6.4 Sending and receiving revisited 30

The other thread (the main program thread) will read from the keyboard, blocking each byte buf[]=new byte[1024];
time, and write to the network: while (true) {
int rc=System.in.read(buf,0,1024);
while (true) { if(rc<=0) break;
int rc=System.in.read(buf,0,1024); outs.write(buf,0,rc);
if(rc<=0) break; }
outs.write(buf,0,rc); outs.close();
} }
}
This solves the problem, the two asynchronous activities, each a read/write loop, are
handled by separately scheduled threads. Notice:
However there is still a decision to make: which end will execute accept and which • main starts and needs one command line argument which it uses as a port number, it
will do connect? In the earlier pair of example programs the “receive” program also creates a ServerSocket and executes accept, it blocks awaiting a connection. This
took on the role of “server”, or acceptor of the connect request, it executed accept and program must be started first.
the “sender” did connect. This was an arbitrary decision, it would have worked if the
roles were exchanged. In the combined version it is completely arbitrary because we • when it gets the connection it creates a separate thread FromRemote with the stream
should be able to right just one program that can both send and receive but we must from the network, it then starts the thread,
make them different just to make one accept and one connect. So we have two, both • the FromRemote thread loops reading from the network connection: ins.read(..)
with identical send and receive code but differing in how the connection is established. and writing to the console: System.out.write(..),
One is called SendAndReceiveAccept0.java, which will be examined first, and the other
SendAndReceiveConnect0.java. • in parallel with the new thread main executes the other loop reading the keyboard
System.in.read(..) and writing to the socket outs.write(..).
6.4.2 The “acceptor” SendAndReceiveAccept0.java
6.4.3 The “connector” SendAndReceiveConnect0.java
class FromRemote extends Thread {
InputStream ins; class FromRemote extends Thread {
public FromRemote(InputStream i){ ins=i; } // identical to FromRemote in SendAndReceiveAccept0.java
public void run() { ...
try { }
byte buf[]=new byte[1024]; public class SendAndReceiveConnect0 {
while (true) { public static void main(String[] args) throws Exception {
int rc=ins.read(buf,0,1024); Socket sock=new Socket(args[0],Integer.parseInt(args[1]));
if(rc<=0) break; OutputStream outs = sock.getOutputStream();
System.out.write(buf,0,rc);
} FromRemote fromRemote=new FromRemote(sock.getInputStream());
} catch (Exception e) { } fromRemote.start();
}
} byte buf[]=new byte[1024];
public class SendAndReceiveAccept0 { while (true) {
public static void main(String[] args) throws Exception { int rc=System.in.read(buf,0,1024);
ServerSocket ssock=new ServerSocket(Integer.parseInt(args[0])); if(rc<=0) break;
Socket sock=ssock.accept(); outs.write(buf,0,rc);
OutputStream outs = sock.getOutputStream(); }
FromRemote fromRemote=new FromRemote(sock.getInputStream()); outs.close();
fromRemote.start(); }
}
31 Java Network Programming 32

Notice: XFer toRemote=new XFer(System.in,sock.getOutputStream());


XFer fromRemote=new XFer(sock.getInputStream(),System.out);
• the only difference is that this program takes two arguments (though it too is naughty, fromRemote.start();
it doesn’t check!), one is the IP address or host name to connect to and the other is the toRemote.start();
port, }
}
• after that it starts a FromRemote thread and itself enters loop. The thread code is
omitted because it is the same as the previous program. The program above is SendAndReceiveAccept1.java, it creates a ServerSocket and
awaits a connection. The other matching “connecting” program is SendAndReceive-
Connect1.java, it isn’t shown, you can guess what it looks like.
6.4.4 Even simpler if you use three threads
In this version the same thread class XFer is used for both asynchronous tasks, it is just
a loop that reads an InputStream and writes an OutputStream. It is parameterised 7 Datagrams
with the two streams. So if one thread, toRemote, is created with System.in as the
InputStream and the OutputStream for the socket then it will read the keyboard and There is another transport service (aswell as TCP) called UDP, it is a datagram service. It
write to the remote host. The other thread is created with input from the socket and output doesn’t require a connection, it can send and receive packets, the packets can be out-of-
to the console. order, they are not retransmitted if they are lost.
The constructor parameters InputStream and OutputStream are abstract classes, UDP datagrams still require a socket (to communicate with the kernel) but it is not
they exist only to be parent classes, so they can take different child class actual param- connected. In Java this is called a DatagramSocket. If the socket is to be used to receive
eters. In the case of InputStream, it is the parent of all non-abstract input streams: datagrams it is bound to a port, if it is for sending then it does not need a port.
The Java type for the datagram is DatagramPacket. It is used for sending and receiv-
FileInputStreams, BufferedInputStreams (that’s what System.in is) and SocketInputStream
ing. A DatagramPacket must be given storage when it is created, this is the buffer that
It’s similar for OutputStream. will contain the message to send or the data received. The storage is an array of bytes,
Lastly note that there are only two asynchronous tasks but three threads, what does that is a more primitive form of String. If the datagram is to be sent it must be given the
the main thread do? If the main thread reaches the end of the function main when other InetAddress and port of the receiver. Here is an example datagram receiver, it just waits
threads are still running, then it doesn’t terminate the program as it would with a single for a datagram and prints it:
thread program, instead it waits for both other threads to finishing before exiting.
import java.io.*;
class XFer extends Thread { import java.net.*;
InputStream ins; OutputStream outs;
public XFer(InputStream i, OutputStream o){ ins=i; outs=o;} public class ReceiveUDP0 {
public void run() { public static void main(String[] args)
try { throws Exception {
byte buf[]=new byte[1024]; int port = Integer.parseInt(args[0]);
while (true) { byte buffer[] = new byte[1024];
int rc=ins.read(buf,0,1024); DatagramSocket socket=new DatagramSocket(port);
if(rc<=0) break; DatagramPacket packet=new DatagramPacket(buffer,1024);
outs.write(buf,0,rc);
} while(true) {
outs.close(); socket.receive(packet);
} catch (Exception e) { } System.out.println("Got packet from "
} + packet.getAddress().getHostName()
} + " port " + packet.getPort() + ": "
public class SendAndReceiveAccept1 { + new String(packet.getData(),0,packet.getLength()));
public static void main(String[] args) throws Exception { }
ServerSocket ssock=new ServerSocket(Integer.parseInt(args[0])); }
Socket sock=ssock.accept(); }
33 Java Network Programming 34

Note: • it creates a DatagramSocket with port, it is the sender,


• it takes its port as a command line argument, and uses it to create a new “listening” • it enters a loop, each time reading a line from the keyboard, if end of file is typed (ˆd)
DatagramSocket, it gets null and stops, otherwise it sends the input to the receiver program and repeats
the loop,
• it creates a DatagramPacket with a byte array of length 1024, there is no receiver
address so this is to store received packets, • it creates a new DatagramPacket. The first argument is the message obtained by
converting the String to a byte array using .getBytes(). It also has to provide the
• it then enters a loop and waits for a datagram by calling receive on the socket: destination InetAddress and port number,
socket.receive(packet);
• it then sends the datagram using socket.send(...).
the packet to put the datagram into is the argument.
• when a packet arrives this program can extract information from the Datagram, the
sender address, the sender’s (ephemeral–more later) port number, and the data.
Here is a sender program:
import java.io.*;
import java.net.*;

public class SendUDP0 {


public static void main(String[] args)
throws Exception {
DatagramSocket socket = new DatagramSocket();
DatagramPacket packet;
InetAddress iaddr = InetAddress.getByName(args[0]);
int port = Integer.parseInt(args[1]);
BufferedReader stdIn =
new BufferedReader(new InputStreamReader(System.in));
String userInput;

userInput = stdIn.readLine();
while (userInput != null) {
packet = new DatagramPacket(userInput.getBytes(),
userInput.length(),iaddr,port);
socket.send(packet);
userInput = stdIn.readLine();
}
stdIn.close();
socket.close();
}
}

Note:
• it takes a destination address and port as a command line arguments, it will use these
to send the datagram,

You might also like