This is an old revision of the document!
Table of Contents
~~SLIDESHOW~~
Network Programming
- Historically error- prone, difficult, complex
- I/O stream library works quite well for TCP/IP
- Threading is also very useful and relatively easy here
- Networking support on the Java Platform fits well with (and supports) standard protocols: HTTP, FTP, TELNET, SMTP etc.
Identifying a Machine
- Uniquely identify a machine from all the others in the world
- IP (Internet Protocol) address that can exist in two forms:
- DNS (Domain Name Service) form:
www.swan.ac.uk
- “Dotted quad” form:
137.44.1.7
- Represented internally by 32 bit number (4.3 billion possibilities).
static InetAddress.getByName()
- Produces
InetAddress
object containing address.
Who Am I?
Finds out your network address when you're connected to the Internet.
- 1 | Example 1: Examine the java.net.InetAddress object (at-m42/Examples/lecture10/whoAmI.groovy)
extern> http://www.cpjobling.org.uk/~eechris/at-m42/Examples/lecture10/whoAmI.groovy
<cli prompt='$'> $ java WhoAmI Usage: WhoAmI MachineName $ java WhoAmI www.swan.ac.uk www.swan.ac.uk/137.44.1.7 </cli> May be useful if your ISP dynamically allocates IP addresses for your dial-up connection.
Clients and Servers
- Two machines must connect
- Server waits around for connection
- Client initiates connection
- Once the connection is made, server & client look identical
- Both ends are turned into
InputStream
andOutputStream
objects, which can then be converted toReader
andWriter
objects.
Testing without a Network
localhost
: the “local loopback” IP address for testing without a network
InetAddress addr = InetAddress.getByName(null)
- Equivalently:
InetAddress.getByName("localhost")
- Or using the reserved IP number for the loopback:
InetAddress.getByName("127.0.0.1")
Port
- Unique “place” in a Machine
- IP address isn’t enough to identify a unique server
- Many servers can exist on one machine
- Process address includes a port number
- When you set up client and server, you must specify IP address and port, so they can find each other
- Not a physical location, but a software abstraction to represent a service
- Ports 1-1023 are reserved, others may be used (up to 64K)1)
Sockets
- Software abstraction used to represent the “terminals” of a connection between two machines.
- Socket is the actual 2-way connector. Can initiate a connection with a server.
ServerSocket
isn't really a socket but more of a “Server Connector” that produces aSocket
as the return value ofaccept( )
, which waits for a connection.- In the end, you get a
Socket
on each machine.
Just Like Files
- in Java, once you have a
Socket
, you callgetInputStream()
andgetOutputStream()
to produce the correspondingInputStream
andOutputStream
objects - You convert these to readers and writers, wrap them in a
BufferedReader
orBufferedWriter
andPrintWriter
- From then on, it’s like reading and writing any other I/O stream!
- groovy simplifies this further by the judicious use of closures.
Simple Client and Server
- Example 2 very simple server that just echoes whatever the client sends (code in the notes) which is closely based on Java equivalent.
- 1| Example 2: very simple server that just echoes whatever the client sends (at-m42/Examples/lecture10/javaServer.groovy)
extern> http://www.cpjobling.org.uk/~eechris/at-m42/Examples/lecture10/javaServer.groovy
Explanation: references to listing …
- Line 7 – create server socket at
ClientServer.PORT
and wait for a connection - Lines 10 and 14 – attach I/O to connection and act as a server
- Lines 16-22 – act as an echo server
- Lines 24 and 28 – finally: always close the two sockets
The Client
- Example 3 Very simple client that just writes to server and echoes what's returned (code in the notes) which is closely based on Java equivalent.
- 1| Example 3: Very simple client that just writes to server and echoes what's returned (at-m42/Examples/lecture10/javaClient.groovy)
extern> http://www.cpjobling.org.uk/~eechris/at-m42/Examples/lecture10/javaClient.groovy
Explanation: references to code …
- Line 3 – open loop-back address
- Line 6 – create socket and connect to
ClientServer.PORT
- Lines 11 and 15 – attach I/O to connection and act as a client
- Lines 17–21 – write to server and echo reply
- Line 23 – finally: close client socket
The First Run
This slide shows a run of these programs.
Server started first: <cli prompt='>'> $ groovy javaServer.groovy </cli> client started in a second command shell window. <cli prompt='>'> $ groovy javaClient.groovy </cli>
Groovy-Socket
- In Groovy
ServerSocket.accept
can take a closure. - Also adds a method
withStreams
that takes a closure to thejava.net.Socket
class. - Streams and sockets are closed after these closures return (even if an IO error occurs) so we don't need any
try
-catch
blocks.
Groovy-server
- l|Example 3: A simpler Groovy server (at-m42/Examples/lecture10/groovyServer.groovy)
extern> http://www.cpjobling.org.uk/~eechris/at-m42/Examples/lecture10/groovyServer.groovy
Here we see how the use of closures simplify the logic of the server application, and also makes it much more readable. The necessary try
-catch
-finally
code that Java needs can be hidden inside the definition of the server.accept(Closure)
and socket.withStreams(Closure)
methods. Similar usability improvements are to be found throughout the Groovy-I/O system. Most commonly used cases are supported, but if you need tighter control, you can always go back to the full Java patterns.
Groovy-client
- 1|Example 4: A simpler Groovy client (at-m42/Examples/lecture10/groovyClient.groovy)
extern> http://www.cpjobling.org.uk/~eechris/at-m42/Examples/lecture10/groovyClient.groovy
Similarly, the client is made much more understandable by use of the socket.withStreams
method. You will also have noted the similarity of the actual code of the client/server logic.
Serving Multiple Clients via Threads
Since the Groovy closure implements the Runnable
interface, to create a server that can handle multiple threads, we simply wrap the server.accept
closure in a while(true)
loop.
- 1|Example 5: A multi-threaded server (at-m42/Examples/lecture10/groovyMultiServer.groovy)
extern> http://www.cpjobling.org.uk/~eechris/at-m42/Examples/lecture10/groovyMultiServer.groovy
When a new client request comes into the server, the accept
closure is activated in a new thread and the server can immediately go back to waiting.
ServeOneJabber
An inner class: extends Thread (see Concurrency) and implements the behaviour of JabberServer in its run method. Constructor: Takes a socket s as a parameter (Line 26) Adds the necessary upstream and downstream IO decorators (Line 28) Calls start() to start the thread [start() calls run()] (Line 36). Run method: Implements the echo behaviour (Line 41) Finally: closes socket s (Line 52)
MultiJabberServer
Typical of a real server process! Line 65: Creates a ServerSocket s. Inside a while-forever loop s.accept() method blocks until a client attempts to connect (line 70) when client connects, s.accept() returns a new Socket socket. Server sends socket to a new ServeOneJabber (creates a new thread to handle this connection – line 72) Server goes back to waiting for next client connection. Finally (will only be called if server is interrupted) closes the ServerSocket – line 80.
Client that tests the MultiJabberServer
MultiJabberClient
Creates lots of client threads (JabberClientThread objects) to test the ability of the Server to handle multiple requests. Constructor (Line 34) takes an internet address. Opens a socket to the server (line 38) Adds IO Decoration to upstream and downstream links (line 45) Class the start() method (line 50) Various finally clauses recover from errors (line 52). Run method (line 65) Sends numbers to server Closes socket when done
MultiJabberClient
Creates a JabberClientThread objects every 100 ms. Each JabberClientThread opens a connection to the server and “jabbers” Up to 40 connections will be made
User Datagram Protocol (UDP)
Previous examples used Transmission Control Protocol (TCP). Very high reliability, message will always get there. Also high overhead User Datagram Protocol (UDP) is an “unreliable” protocol which is much faster, but the messages won’t always get there Datagrams You make your own packets and write the address on the outside, send it Based on packet contents, recipient decides whether they got everything, sends a message if they didn’t, you retransmit Reliability must be enforced by your program, not by the UDP protocol
Communicating with Datagrams
DatagramSocket on both server and client Sends and receives DatagramPackets No “connection”: datagram just shows up Only server must have fixed IP & port number DatagramPacket contains message of any length up to 64K bytes, and IP address and socket # of destination DatagramPacket objects are used for holders of both sent and received datagrams
For Sending and Receiving
For receiving, needs a buffer:
DatagramPacket(buf, length)
For sending, needs buffer, IP address and port number:
DatagramPacket(buf, length, inetAddress, port)
Here, buf already contains data to be sent, length is amount of buffer you want in datagram In the example, the server just echoes datagrams, client threads send datagrams & wait for echo:
Examples (for Self Study)
Dgram.java – defines a UPD datagram ChatterServer.java – a version of MultiJabberServer using Dgram objects. ChatterClient.java – a version of MultiJabberClient using Dgram objects.
Firewall Warning
Problem: program using port 8080 works fine, except when client is behind a firewall Firewall doesn’t like to see anything but ordinary network connections to WWW server via its standard HTTP port 80 A solution in is to use CGI programming Java servlet server solves this problem as it communicates via HTTP port 80.
Lab Exercises
1. Compile and run the JabberServer and JabberClient programs in this chapter. Now edit the files to remove all the buffering for the input and output, then compile and run them again to observe the results. 2. Create a server that asks for a password, then opens a file and sends the file over the network connection. Create a client that connects to this server, gives the appropriate password, then captures and saves the file. Test the pair of programs on your machine using the localserver (the local loopback IP address 127.0.0.1 produced by calling InetAddress.getByName(null)). 3. Modify the server in exercise 2 so that it uses multithreading to handle multiple clients. 4. Modify JabberClient so that it doesn’t explicitly flush( ) its output and observe the effect.
- 1| Example 1: Everything is an object (at-m42/Examples/lecture02/example1.groovy)
extern> http://www.cpjobling.org.uk/~eechris/at-m42/Examples/lecture02/example1.groovy
Notes …