Transcript jnet11
Client/Server Distributed Systems
240-322, Semester 1, 2005-2006
11. Java Networking
Objectives
– describe basic networking in Java
– Web page retrieval and sockets programming
240-322 Cli/Serv.: jnet/11
1
Contents
1. Networking Restrictions in Java
2. Basic Networking Classes
3. Sockets (Java Style)
4. Retrieving a Web Page
– 4 different approaches
5. A Stream Socket Client/Server
240-322 Cli/Serv.: jnet/11
continued
2
6.
7.
8.
240-322 Cli/Serv.: jnet/11
A Datagram Socket Client/Server
Networked Tic-Tac-Toe
More Information
3
1. Networking Restrictions in Java
Many
browsers place networking restrictions
on applets
– usually communication is limited to being
between your machine and the one where the
applet came from
There
are no restrictions on Java applications
or when using appletviewer
240-322 Cli/Serv.: jnet/11
4
Relaxing Security
Applets
can be signed with trusted
certificates
– a browser can be configured to relax security
depending on an applet’s signature
– an advanced topic
240-322 Cli/Serv.: jnet/11
5
2. Basic Networking Classes
The
J2SE documentation for java.net lists
over 30 classes. A few of the key ones:
InetAddress
– the class that represents IP addresses and
contains operations for manipulating them
see
240-322 Cli/Serv.: jnet/11
section 2.1
continued
6
URL
– used to retrieve the Web page at the given URL
URLConnection
– also used to retrieve a Web page
– allows extra parameters to be sent to the URL
e.g
240-322 Cli/Serv.: jnet/11
HTTP request headers
continued
7
Socket
– the client-side socket class for TCP
ServerSocket
– the server-side socket class for TCP
DatagramSocket
– allows a client or server to send/receive UDP
packets
240-322 Cli/Serv.: jnet/11
8
2.1. Finding an IP Address
Java’s InetAddress
class makes the
mapping between hostnames and IP
addresses much easier than in UNIX.
For
details, look at the the documentation
for java.net.InetAddress
240-322 Cli/Serv.: jnet/11
9
WhatIP.java
import java.io.*;
import java.net.*;
public class WhatIP
{
public static void main(String args[])
throws IOException
{ InetAddress addr =
InetAddress.getByName(args[0]);
System.out.println("Inet address is "+ addr);
}
}
240-322 Cli/Serv.: jnet/11
10
Use
240-322 Cli/Serv.: jnet/11
Carried out from a DOS
prompt on my Windows machine.
11
3. Sockets (Java Style)
1.
Stream Sockets
– the client/server connection exists for the entire
duration of the request and answer
similar
to a telephone call
– a connection-oriented service
corresponds to TCP
– Java has separate classes for client and
server stream sockets (see section 5)
240-322 Cli/Serv.: jnet/11
12
2.
Datagram Sockets
– the client/server send messages (packets,
datagrams) to each other
similar
to the postal service
– a connectionless service
corresponds to UDP
– Java has classes for datagram sockets and
packets (see section 6).
240-322 Cli/Serv.: jnet/11
13
3.1. Pinging
ping is a DOS command, not Java.
uses the ICMP protocol's ECHO_REQUEST
datagram. The host’s answer is an ICMP
ECHO_RESPONSE.
ping
240-322 Cli/Serv.: jnet/11
14
ICMP packets
can only be created via a
socket of type SOCK_RAW.
– but Java only supports SOCK_STREAM (TCP)
and SOCK_DGRAM (UDP) sockets
Our
solution: use a TCP connection to the
daytime service to pretend to ping
– the daytime server listens at port 13
240-322 Cli/Serv.: jnet/11
15
3.2. DayPing.java
JJ2, p.677
import java.io.*;
import java.net.*;
public class DayPing {
public static void main(String args[])
throws Exception
{
if (args.length != 1) {
System.out.println(
"Usage: java DayPing <machine name>");
System.exit(0);
}
:
240-322 Cli/Serv.: jnet/11
16
String machine = args[0];
Socket so = new Socket(machine, 13);
// daytime server listens at port 13
BufferedReader br =
new BufferedReader(
new InputStreamReader(
so.getInputStream() ) );
System.out.println( machine +
" is alive at " + br.readLine());
so.close();
} // end of main()
} // end of DayPing class
240-322 Cli/Serv.: jnet/11
17
Notes
converts the socket
connection into a BufferedReader
DayPing.java
– this allows readLine() to be used for socket
input
Using
layered streams to add I/O
functionality on top of sockets is a powerful
feature of Java.
240-322 Cli/Serv.: jnet/11
18
Use
All the examples were tested on
my Windows machine
C> javac DayPing.java
C> java DayPing calvin
calvin is alive at Sat May
7 13:46:06 2005
C> java DayPing fourdots
Exception in thread "main"
java.net.ConnectException: Connection refused:
no further information
at java.net.PlainSocketImpl.socketConnect
(Native Method)
at java.net.PlainSocketImpl.doConnect...
:
at ping.main(DayPing.java:23)
240-322 Cli/Serv.: jnet/11
continued
19
After a wait
C> java DayPing takasilla
Exception in thread "main"
java.net.UnknownHostException: takasilla
at java.net.PlainSocketImpl.
connect(Unknown Source)
:
at ping.main(DayPing.java:23)
After a long wait
C> java DayPing www.amazon.com
Exception in thread "main"
java.net.NoRouteToHostException: Operation
timed out: connect
at java.net.PlainSocketImpl.
socketConnect(Native Method)
:
at ping.main(DayPing.java:23)
240-322 Cli/Serv.: jnet/11
20
3.3. Why Doesn't DayPing Work?
The
examples that don't work show three
different errors:
– ConnectException
– UnknownHostException
– NoRouteToHostException
The
"unknown host" exception is caused by
an incorrect IP address.
240-322 Cli/Serv.: jnet/11
continued
21
The
"connection" exception probably means
that the server is unavailable (switched off)
– this can be confirmed for a TCP service by
trying to connect to it with telnet:
$ telnet fourdots 13
Trying 172.30.255.4...
telnet: Unable to connect to remote host:
Connection refused
$
executed from a different
machine (fivedots)
240-322 Cli/Serv.: jnet/11
continued
22
The
"no route to host" exception usually
means that there is a firewall preventing the
connection from being made.
telnet
response:
A long wait,
and then...
$ telnet www.amazon.com 13
Trying 207.171.163.90...
telnet: Unable to connect to remote host:
Connection timed out
$
tried on (fivedots)
240-322 Cli/Serv.: jnet/11
23
3.4. Firewalls at PSU
(simplified)
University
Departmental firewall
(no external socket creation;
URLs allowed)
calvin
takasila
ratree
Univ. firewall
(no external socket creation;
URLs only through
the ‘cache’ proxy)
fivedots
CoE Department
240-322 Cli/Serv.: jnet/11
The Internet
8080
cache
24
Ordinary
users (i.e. students) cannot write
socket-based programs that communicate
outside PSU
– this is true in any language (Java, C, etc.)
But
programs can retrieve Web pages (and
other things) using the Java URL class
– the URL request must go through PSU's cache
machine
240-322 Cli/Serv.: jnet/11
25
URLs and Sockets
From
your data communications course,
you may recall that the Web protocol,
HTTP, is built on top of TCP/IP.
Java's
URL class uses stream sockets
(TCP/IP) for its implementation
– so why does it get past cache?
240-322 Cli/Serv.: jnet/11
continued
26
cache accepts socket links to valid Web
servers, but also checks that the HTTP GET
(or POST) message includes additional
valid HTTP headers.
– all of this HTTP stuff is carried out by the URL
class for us
240-322 Cli/Serv.: jnet/11
27
4. Retrieving a Web Page
Five
ways of obtaining a Web page:
– 1. use a socket, and send a GET message to the
server
see
GetSocketPage.java
– 2. use a URL object, and read the page via a
stream
see
240-322 Cli/Serv.: jnet/11
GetURLPage.java
continued
28
– 3. use a URL object, and display the page in a
browser
see
showPage.java
– 4. display a URL in an JEditorPane
see
ShowURLPage.java
– 5. use a HTTP URL connection, and send a
GET message
see
240-322 Cli/Serv.: jnet/11
Java’s networking tutorial
29
4.1. Sockets and GET
GetSocketPage.java
retrieves the page:
http://<host name>/index.html
e.g.
http://fivedots.coe.psu.ac.th/index.html
It
prints the text of the page to stdout.
240-322 Cli/Serv.: jnet/11
continued
30
It
opens a socket at port 80 for the host,
which is the usually place where the Web
server is listening.
It
sends the HTTP GET message:
GET /index.html
240-322 Cli/Serv.: jnet/11
31
Diagram
GET /index.html
80
GetSocketPage
client
240-322 Cli/Serv.: jnet/11
Web page
(as text)
Web
server
host
32
GetSocketPage.java
import java.io.*;
import java.net.*;
public class GetSocketPage
{
public static void main(String args[])
throws IOException
{
Socket sock = new Socket(args[0],80);
:
240-322 Cli/Serv.: jnet/11
33
BufferedReader dis =
new BufferedReader(
new InputStreamReader(
sock.getInputStream() ));
PrintStream ps =
new PrintStream(
sock.getOutputStream() );
ps.println("GET /index.html");
String line;
while ((line = dis.readLine()) != null)
System.out.println(line);
sock.close();
}
} // end of GetSocketPage.java
240-322 Cli/Serv.: jnet/11
34
Notes
converts the socket
connection into a BufferedReader for input,
and a PrintStream for output
GetSocketPage.java
– uses readLine()for socket input
– uses println() for socket output
240-322 Cli/Serv.: jnet/11
35
Use
C> javac GetSocketPage.java
text of Web page
printed to stdout
C> java GetSocketPage fivedots
<html>
<head>
<title>Un title page</title>
</head>
<meta http-equiv="Content-Type"
content="text/html; charset=windows-874">
<style type="text/css">
:
C>
240-322 Cli/Serv.: jnet/11
36
But...
C> java GetSocketPage www.amazon.com
Exception in thread "main"
java.net.ConnectException:
Connection timed out: connect
at java.net.PlainSocketImpl.
socketConnect(Native Method)
:
at GetSocketPage.main(GetSocketPage.java:18)
The firewall around PSU
prevents Web server
access by sockets.
240-322 Cli/Serv.: jnet/11
continued
37
cache
rejected the GET message to the
external site since the message didn't
include additional HTTP headers.
These
can be supplied by us, but it's easier
to use the URL class.
240-322 Cli/Serv.: jnet/11
38
4.2. URL Object
avoids the firewall
problem with sockets by using a URL object.
GetURLPage.java
A URL
object allows a Web page to be
retrieved as a stream of text
– our program prints the text to stdout.
240-322 Cli/Serv.: jnet/11
39
GetURLPage.java
import java.net.*;
import java.io.*;
public class GetURLPage {
public static void main(String args[])
{
try {
URL url = new URL(args[0]);
BufferedReader dis =
new BufferedReader(
new InputStreamReader(
url.openStream() ));
:
240-322 Cli/Serv.: jnet/11
40
String line;
while ( (line = dis.readLine()) != null )
System.out.println(line);
dis.close();
}
catch (Exception e)
{ System.out.println(e); }
}
} // end of GetURLPage.java
240-322 Cli/Serv.: jnet/11
41
Notes
A stream
for the URL object is obtained
using openStream()
– after that the same input stream layering
technique is used as in GetSocketPage.java
– there is no need to send a GET message
240-322 Cli/Serv.: jnet/11
42
Use
C> javac GetURLPage.java
C> java GetURLPage http://www.amazon.co.uk
java.net.ConnectException:
Connection timed out: connect
after a
long wait
C> java -DproxySet=true
-DproxyHost=cache.psu.ac.th
-DproxyPort=8080
GetURLPage http://www.amazon.com/
<html>
<head>
<title>Amazon Page</title>
</head>
<body bgcolor=#ffffff test=#000000>
<H1>
:
C>jnet/11
240-322 Cli/Serv.:
typed on
one line
43
Ordinary
users can access outside PSU by
using URLs, but they must route their
requests via PSU cache machine.
240-322 Cli/Serv.: jnet/11
44
Batch Files for Long Commands
GetURLPage.bat contains:
@echo off
echo Executing GetURLPage...
java -DproxySet=true
-DproxyHost=cache.psu.ac.th
-DproxyPort=8080 GetURLPage %1
Use:
c> GetURLPage http://www.amazon.co.uk
: // same output as last slide
240-322 Cli/Serv.: jnet/11
45
Proxy Username/Password
A further
level of firewall security is to
require the user to enter a username and
password
– called proxy authorization
Java
has network support for authorization
– it allows a username and password to be sent by
a client program to the firewall
240-322 Cli/Serv.: jnet/11
continued
46
A good
tutorial:
– “Jump a Proxy/Firewall and Live to Tell About it”
http://www.devx.com/upload/free/features/
javapro/2000/03mar00/te0003/te0003.asp
Slightly
modified code is in
GetThroughProxy.java at:
http://fivedots.coe.psu.ac.th/
Software.coe/Cliserv/
Code%20Examples/Java%20Code/
Basic%20Networking/
240-322 Cli/Serv.: jnet/11
47
4.3. Passing a URL to a Browser
If
the Java code is in an applet, then the
downloaded URL can be displayed in the
browser.
displays a user-specified
Web page in the (Opera) browser, using the
ShowPage.java applet.
showPage.html
240-322 Cli/Serv.: jnet/11
48
Usage
The dialog box appears in front
of the browser window.
240-322 Cli/Serv.: jnet/11
continued
49
Loaded
Page:
240-322 Cli/Serv.: jnet/11
50
showPage.html
<html><head>
<title>Web Page Loading Applet</title></head>
<body>
<h1>Web Page Loading Applet</h1>
<P>Applet is placed here...
<applet code="ShowPage.class"
width=300 height=50>
</applet>
</P>
</body></html>
240-322 Cli/Serv.: jnet/11
51
showPage.java
import
import
import
import
java.net.*;
javax.swing.*;
java.applet.AppletContext;
javax.swing.JOptionPane;
public class ShowPage extends JApplet
{
public void init()
{
try {
String urlString =
JOptionPane.showInputDialog(
"Enter a URL:");
URL url = new URL(urlString);
:
240-322 Cli/Serv.: jnet/11
52
AppletContext browser = getAppletContext();
browser.showDocument(url);
}
catch (Exception e)
{ System.out.println(e); }
} // end of init()
} // end of ShowPage
240-322 Cli/Serv.: jnet/11
53
Notes
The
download only works because the
browser is set up to work through cache.
There
are no Java security restrictions on a
applet passing a URL to a browser to be
displayed.
240-322 Cli/Serv.: jnet/11
continued
54
A URL is
downloaded with showDocument(),
which must be called in the applet’s
environment (i.e. the browser):
– AppletContext browser =
getAppletContext();
browser.showDocument(url);
The
URL is automatically loaded into the
browser, replacing showPage.html.
240-322 Cli/Serv.: jnet/11
continued
55
There
is a two-argument version of
showDocument() that can load URLs into
frames.
D&D
contains a more complex example
(SiteSelector.java, ch. 21) which allows
the user to select a URL from a list.
240-322 Cli/Serv.: jnet/11
56
4.4. Displaying a URL with JEditorPane
The
Swing GUI includes JEditorPane
which allows 'structured' text to be
displayed and edited.
– offers basic support for plain text, RTF, and
HTML
– see javax.swing.JEditorPane
240-322 Cli/Serv.: jnet/11
continued
57
A JEditorPane
can be filled by calling
setPage() with a URL string argument.
also has support for capturing
hyperlink clicks as events.
JEditorPane
240-322 Cli/Serv.: jnet/11
continued
58
With
these features, it is possible to write a
basic Web browser!
has a text field for the
user to enter a URL
ShowURLPage.java
– the resulting downloaded page is displayed in a
JEditorPane
– if a link is clicked inside the pane, then its page
will be loaded automatically
240-322 Cli/Serv.: jnet/11
continued
59
I clicked on
“School of Advanced...”
240-322 Cli/Serv.: jnet/11
60
ShowURLPage’s Event Model
X
GUI
enter
contents
^
action
events
hyperlink
events
Code
240-322 Cli/Serv.: jnet/11
hyperlinkUpdate() {...}
actionPerformed() {...}
61
ShowURLPage.java
import
import
import
import
import
import
java.awt.*;
java.awt.event.*;
java.net.*;
java.io.*;
javax.swing.*;
javax.swing.event.*;
public class ShowURLPage extends JFrame
{
private JTextField enter;
private JEditorPane contents;
:
240-322 Cli/Serv.: jnet/11
62
public ShowURLPage()
{
super("Simple Web Browser");
Container c = getContentPane();
enter = new JTextField("Enter file URL here");
enter.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e )
{ getPage(e.getActionCommand());}
});
c.add(enter, BorderLayout.NORTH);
:
240-322 Cli/Serv.: jnet/11
63
contents = new JEditorPane();
contents.setEditable(false);
contents.addHyperlinkListener(
new HyperlinkListener() {
public void hyperlinkUpdate(
HyperlinkEvent e)
{
if(e.getEventType() ==
HyperlinkEvent.EventType.ACTIVATED)
getPage(e.getURL().toString());
}
});
:
240-322 Cli/Serv.: jnet/11
64
c.add( new JScrollPane(contents),
BorderLayout.CENTER);
setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE);
setSize(400, 300);
setVisible(true);
} // end of ShowURLPage()
240-322 Cli/Serv.: jnet/11
65
private void getPage(String location)
{
setCursor(Cursor.getPredefinedCursor(
Cursor.WAIT_CURSOR));
try {
contents.setPage(location);
enter.setText(location);
}
catch (IOException io) {
JOptionPane.showMessageDialog(this,
"Error retrieving specified URL",
"Bad URL",
JOptionPane.ERROR_MESSAGE);
}
setCursor( Cursor.getPredefinedCursor(
Cursor.DEFAULT_CURSOR) );
} // end of getPage()
240-322 Cli/Serv.: jnet/11
66
public static void main(String args[])
{ new ShowURLPage(); }
} // end of ShowURLPage class
240-322 Cli/Serv.: jnet/11
67
Use
C> javac ShowURLPage.java
C> java ShowURLPage
// A request for http://www.cs.ait.ac.th/~ad
// causes a “Bad URL” dialog box to appear
C> java -DproxySet=true
-DproxyHost=cache.psu.ac.th
-DproxyPort=8080 ShowURLPage
Typed all on one line.
The window shown on the left of slide 60 appears.
240-322 Cli/Serv.: jnet/11
68
Notes
The JEditorPane
must be set uneditable so
that hyperlinks events can be captured.
events include: ENTERED, EXITED,
and ACTIVATED.
Hyperlink
– see javax.swing.event.HyperlinkEvent
240-322 Cli/Serv.: jnet/11
continued
69
getPage()
calls setPage() to display a URL
in the JEditorPane
– the call is surrounded by changes to the cursor
icon so things look busy
getPage()
is called in two possible ways:
– as a response to pressing enter in the textfield
– as a response to a link being clicked
240-322 Cli/Serv.: jnet/11
70
5. A Stream Socket Client/Server
AlienClient.java
AlienServer1.java
Initial Internet
4444 Server socket
connection
socket
input and
output
streams
240-322 Cli/Serv.: jnet/11
socket
for client
comms.
input and
output
streams
the new socket is
made with accept()
71
The
server creates a new socket when a
client contacts it
– client/server communication via the new socket
– this frees up the main server socket to receive
connections from other clients
– AlienServer1.java is an iterative server
it
240-322 Cli/Serv.: jnet/11
can only process one client at a time
continued
72
Our
client and server both run on localhost.
AlienServer1
actions:
– wait for a client connection
– after a connection, wait for a message from the
client
– respond depending on the content of the
message
– close the client connection, and loop, waiting
for another client
240-322 Cli/Serv.: jnet/11
continued
73
Diagram for Client Processing
AlienClient.java
AlienServer1.java
1. send message
4. send answer
2. analyse message
3. print message locally
5. close socket
240-322 Cli/Serv.: jnet/11
74
AlienServer1.java
import java.io.*;
import java.net.*;
public class AlienServer1 {
public static void main(String args[])
throws IOException
{
Socket sock;
BufferedReader in;
PrintStream out;
ServerSocket servsock =
new ServerSocket(4444);
:
240-322 Cli/Serv.: jnet/11
75
while (true) {
// wait for the next client connection
sock = servsock.accept();
// Get I/O streams from the socket
out = new PrintStream(
sock.getOutputStream() );
in = new BufferedReader(
new InputStreamReader(
sock.getInputStream() ) );
:
240-322 Cli/Serv.: jnet/11
76
// get client message and respond
String msg = in.readLine();
System.out.println(" Received: " + msg);
if (msg.indexOf("hello") > -1) {
System.out.println(" Friendly contact made");
out.println("Welcome friend");
}
else {
System.out.println(" Probably an alien");
out.println("ET go home");
}
out.flush();
// Close this connection,
// (not the overall server socket)
sock.close();
}
} // of main()
}// end of AlienServer1
240-322 Cli/Serv.: jnet/11
77
The client: AlienClient.java
AlienClient.java’s
–
–
–
–
actions:
open a connection with the server
send a message taken from the command line
receive and print the server’s response
close
240-322 Cli/Serv.: jnet/11
78
AlienClient.java
import java.io.*;
import java.net.*;
public class AlienClient {
public static void main(String args[])
throws IOException {
Socket sock = new Socket("localhost", 4444);
// Get I/O streams from the socket
BufferedReader br =
new BufferedReader(
new InputStreamReader(
sock.getInputStream()) );
PrintStream ps = new PrintStream(
sock.getOutputStream() );
:
240-322 Cli/Serv.: jnet/11
79
// Send a message from the command line
ps.println(args[0]);
ps.flush();
// Read server’s response
String line = br.readLine();
System.out.println(
"Got this from server:\n
" + line);
sock.close();
} // end of main()
} // end of AlienClient class
240-322 Cli/Serv.: jnet/11
80
Use
Client:
Server:
I used two separate DOS windows
on the same machine.
240-322 Cli/Serv.: jnet/11
81
Telnet Client (from fivedots)
I typed this
Server:
240-322 Cli/Serv.: jnet/11
82
A More Complex Example
D&D
gives a larger stream socket
client/server example (ch. 21):
– object input and output streams are used
– the sequence of communication is more complex
the
client maintains a long-lived link with the server
until it sends a “TERMINATE” string
240-322 Cli/Serv.: jnet/11
83
5.1. A Concurrent Server
uses threads to handle
multiple clients concurrently.
AlienServer2.java
Three
main advantages:
– the server code is simpler since server
processing is in a separate class called Worker
– clients do not have to wait
– the server is more scaleable
240-322 Cli/Serv.: jnet/11
84
AlienServer2 Visually
AlienServer2
AlienClient clients
4444
Worker
threads
each Worker thread can
deal with multiple messages
from its client
240-322 Cli/Serv.: jnet/11
85
5.2. Java Threads (Briefly)
There
are two ways to create a thread:
– extend the Thread class
– write a class to implement the Runnable
interface
use the first approach since Worker
does not need to extend any other classes.
We
240-322 Cli/Serv.: jnet/11
continued
86
A class
extended from Thread must define
the run() method:
class Worker extends Thread {
public void run()
{ ... }
}
A threaded
start():
object is started by calling
Worker w = new Worker(...):
w.start();
The
thread will call run() itself from
within start().
240-322 Cli/Serv.: jnet/11
87
5.3. AlienServer2.java
import java.io.*;
import java.net.*;
public class Worker extends Thread
{ private Socket sock;
private int id;
public Worker(Socket s, int c)
{ sock = s;
id = c;
}
:
240-322 Cli/Serv.: jnet/11
88
public void run()
{
// Get I/O streams from the socket
try {
PrintStream out = new PrintStream(
sock.getOutputStream() );
BufferedReader in =
new BufferedReader(
new InputStreamReader(
sock.getInputStream() ));
:
240-322 Cli/Serv.: jnet/11
89
The worker contains much the same
client processing code as the iterative
server.
// get client messages and respond
String msg;
while ((msg = in.readLine()) != null) {
System.out.println(" Worker "+id+
" received: "+ msg);
if (msg.indexOf("hello") > -1)
out.println("Welcome friend")
else
out.println("ET go home");
out.flush();
}
:
240-322 Cli/Serv.: jnet/11
90
// Close this connection,
// (not the overall server socket)
System.out.println(" Worker " + id +
" finished");
sock.close();
}
catch(IOException ioe)
{System.out.println(ioe); }
} // end of run()
} // end of Worker class
240-322 Cli/Serv.: jnet/11
91
public class AlienServer2
{
public static void main(String args[])
throws IOException
{ Socket sock;
ServerSocket servsock =
new ServerSocket(4444, 6);
while (true) {
// wait for the next client connection
sock = servsock.accept();
new Worker(sock).start();
}
} // of main()
} // of AlienServer2 class
240-322 Cli/Serv.: jnet/11
92
Use
240-322 Cli/Serv.: jnet/11
Server:
93
Client on fivedots
240-322 Cli/Serv.: jnet/11
94
Two Local Clients (one closed)
240-322 Cli/Serv.: jnet/11
95
6. A Datagram Socket Client/Server
UDPClient
Datagram
socket
UDPServer
packets
any
port
msg
5000
Datagram
socket
echo
240-322 Cli/Serv.: jnet/11
96
6.1. Server Event Model
X
^
display
1) receive from
client
GUI
Code
waitForPackets() {...}
packet
packet
240-322 Cli/Serv.: jnet/11
2) echo back
to client
97
6.2. UDPServer.java
import
import
import
import
import
java.io.*;
java.net.*;
java.awt.*;
java.awt.event.*;
javax.swing.*;
public class UDPServer extends JFrame
{
private JTextArea display;
:
240-322 Cli/Serv.: jnet/11
98
public UDPServer()
{ super("UDP Server");
display = new JTextArea();
getContentPane().add(
new JScrollPane( display),
BorderLayout.CENTER );
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 300);
show();
DatagramSocket socket = null;
try {
socket = new DatagramSocket( 5000 );
}
catch(SocketException se) {
se.printStackTrace();
System.exit(1);
}
waitForPackets(socket);
} // end of UDPServer()
240-322 Cli/Serv.: jnet/11
99
private void waitForPackets(DatagramSocket socket)
{
DatagramPacket sendPacket, receivePacket;
while (true) {
try {
// set up packet data structure
byte data[] = new byte[100];
receivePacket =
new DatagramPacket(data, data.length);
// wait for packet from client
socket.receive(receivePacket);
:
240-322 Cli/Serv.: jnet/11
100
// process client packet
display.append("\nPacket received:" +
"\nFrom host: "+receivePacket.getAddress()+
"\nHost port: " + receivePacket.getPort() +
"\nLength: " + receivePacket.getLength() +
"\nContaining:\n\t" +
new String(receivePacket.getData(), 0,
receivePacket.getLength()));
:
240-322 Cli/Serv.: jnet/11
101
// echo packet info back to client
display.append(
"\n\nEcho data to client...");
sendPacket =
new DatagramPacket(
receivePacket.getData(),
receivePacket.getLength(),
receivePacket.getAddress(),
receivePacket.getPort() );
socket.send( sendPacket );
display.append("Packet sent\n");
display.setCaretPosition(
display.getText().length() );
}
:
240-322 Cli/Serv.: jnet/11
102
catch(IOException io) {
display.append(io.toString() + "\n");
io.printStackTrace();
}
}
} // end of waitForPackets{}
public static void main( String args[] )
{
new UDPServer(); }
} // end of UDPServer
240-322 Cli/Serv.: jnet/11
103
Server Notes
The
server creates one datagram socket at
port 5000:
socket = new DatagramSocket(5000);
Datagram
socket creation must be inside a
try/catch block.
240-322 Cli/Serv.: jnet/11
continued
104
The
server loops inside waitForPackets()
– creates an empty packet (100 bytes long)
– blocks inside receive()
When receive()
returns, the packet
contains data and:
– the Internet address of the sender
– the port number of the sender
– the actual length of the data
240-322 Cli/Serv.: jnet/11
continued
105
The
packet information can be accessed via
methods. e.g.:
receivePacket.getPort();
receivePacket.getData();
receive()
240-322 Cli/Serv.: jnet/11
must be in a try/catch block.
continued
106
The
server echoes the datagram back to the
client at the address and port obtained from
the client’s message:
sendPacket = new DatagramPacket(
receivePacket.getData(),
receivePacket.getLength(),
receivePacket.getAddress(),
receivePacket.getPort() );
socket.send(sendPacket);
send()
240-322 Cli/Serv.: jnet/11
must be in a try/catch block.
107
6.3. Client Event Model
X
GUI
enter
^
display
Code
1) send to server
actionPerformed() {...}
waitForPackets() {...}
2) receive echo
from sender
240-322 Cli/Serv.: jnet/11
action
events
packet
packet
108
6.4. UDPClient.java
import
import
import
import
import
java.io.*;
java.net.*;
java.awt.*;
java.awt.event.*;
javax.swing.*;
public class UDPClient extends JFrame
implements ActionListener
{
private JTextField enter;
private JTextArea display;
private DatagramSocket socket;
:
240-322 Cli/Serv.: jnet/11
109
public UDPClient()
{
super("UDP Client");
enter = new JTextField("Type message here");
enter.addActionListener(this);
getContentPane().add(enter,BorderLayout.NORTH);
display = new JTextArea();
getContentPane().add(new JScrollPane(display),
BorderLayout.CENTER);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 300);
setVisible(true);
:
240-322 Cli/Serv.: jnet/11
110
try {
socket = new DatagramSocket();
}
catch(SocketException se) {
se.printStackTrace();
System.exit(1);
}
waitForPackets();
} // end of UDPClient()
240-322 Cli/Serv.: jnet/11
111
private void waitForPackets()
{
DatagramPacket receivePacket;
while (true) {
try {
// set up packet data structure
byte data[] = new byte[100];
receivePacket =
new DatagramPacket(data, data.length);
// wait for packet from server
socket.receive(receivePacket);
:
240-322 Cli/Serv.: jnet/11
112
// process packet from server
display.append("\nPacket received:" +
"\nFrom host: "+receivePacket.getAddress()+
"\nHost port: " + receivePacket.getPort() +
"\nLength: " + receivePacket.getLength() +
"\nContaining:\n\t" +
new String( receivePacket.getData(), 0,
receivePacket.getLength()));
display.setCaretPosition(
display.getText().length() );
}
catch(IOException ex) {
display.append(ex.toString()+"\n" );
ex.printStackTrace();
}
}
} // end of waitForPackets()
240-322 Cli/Serv.: jnet/11
113
public void actionPerformed(ActionEvent e)
{
DatagramPacket sendPacket;
try {
display.append(
"\nSending packet containing: " +
e.getActionCommand() + "\n" );
String s = e.getActionCommand();
byte data[] = s.getBytes();
sendPacket = new DatagramPacket(
data, data.length,
InetAddress.getLocalHost(), 5000);
socket.send(sendPacket);
:
240-322 Cli/Serv.: jnet/11
114
display.append("Packet sent\n");
display.setCaretPosition(
display.getText().length() );
}
catch (IOException ex) {
display.append(ex.toString()+"\n");
ex.printStackTrace();
}
}
// end of actionPerformed()
public static void main( String args[] )
{
new UDPClient(); }
} // end of UDPClient
240-322 Cli/Serv.: jnet/11
115
Client Notes
The
client gets the data for each packet
from the user entering a string into a
TextField.
The
client creates a datagram socket with no
specified port number:
socket = new DatagramSocket();
240-322 Cli/Serv.: jnet/11
continued
116
In actionPerformed(),
the user’s input is
converted into a packet, and sent to the
server:
sendPacket = new DatagramPacket(
data, data.length(),
InetAddress.getLocalHost(), 5000);
socket.send(sendPacket);
The
code assumes that the server is on the
same machine as the client, and attached to
port 5000.
240-322 Cli/Serv.: jnet/11
continued
117
The
client receives the echoed reply in
waitForPackets():
– the loop blocks inside receive() until a
packet arrives from the server
– the packet details are displayed in the
JTextArea
The
blocked waitForPackets() does not
stop the user from entering more strings for
the client to send out
– the GUI always runs in a separate thread
240-322 Cli/Serv.: jnet/11
118
Tested by starting the client and server in
two separate DOS windows.
6.5. Use
1. message sent to server
3. Echoed message
received from the server
240-322 Cli/Serv.: jnet/11
2. Client message
received and echoed
continued
119
Another message sent and echoed back:
240-322 Cli/Serv.: jnet/11
120
7. Networked Tic-Tac-Toe
D&D Section 21.8, p.1031
Server
thread
thread
synchronized
validMove()
5000
data
Client:
Player ‘X’
Client:
Player ‘O’
thread
thread
240-322 Cli/Serv.: jnet/11
data
121
Output
240-322 Cli/Serv.: jnet/11
p.1041-1042
122
8. More Information
Chapter 21, Deitel & Deitel (D&D)
http://java.coe.psu.ac.th/ForMember/
Books.html#Network
Killer
Game Programming in Java
Chapter 29, Network Basics
http://fivedots.coe.psu.ac.th/~ad/jg/ch18/
240-322 Cli/Serv.: jnet/11
123
Core
Java 2, Vol II - Advanced Features
Cay S. Horstmann & Gary Cornell
Sun Microsystems Press, 2001,
chapter 3
– multithreaded server, sending e-mail,
URLConnection, HTTP POST
– http://java.coe.psu.ac.th/ForMember/
Books.html#Network
240-322 Cli/Serv.: jnet/11
124
Aj.
Somchai's Java Site
– Network and Distributed Programming Books
http://java.coe.psu.ac.th/ForMember/
Books.html#Network
240-322 Cli/Serv.: jnet/11
125