Title: Java Network Programming
1Java Network Programming
- Elliotte Rusty Harold
- elharo_at_metalab.unc.edu
- http//metalab.unc.edu/javafaq/slides/
2We will learn how Java handles
- Internet Addresses
- URLs
- CGI
- Sockets
- Server Sockets
- UDP
3I assume you
- Understand basic Java syntax and I/O
- Have a users view of the Internet
- No prior network programming experience
4Applet Network Security Restrictions
- Applets may
- send data to the code base
- receive data from the code base
- Applets may not
- send data to hosts other than the code base
- receive data from hosts other than the code base
5Some Background
- Hosts
- Internet Addresses
- Ports
- Protocols
6Hosts
- Devices connected to the Internet are called
hosts - Most hosts are computers, but hosts also include
routers, printers, fax machines, soda machines,
bat houses, etc.
7Internet addresses
- Every host on the Internet is identified by a
unique, four-byte Internet Protocol (IP) address.
- This is written in dotted quad format like
199.1.32.90 where each byte is an unsigned
integer between 0 and 255. - There are about four billion unique IP addresses,
but they arent very efficiently allocated
8Domain Name System (DNS)
- Numeric addresses are mapped to names like
www.blackstar.com or star.blackstar.com by DNS. - Each site runs domain name server software that
translates names to IP addresses and vice versa - DNS is a distributed system
9The InetAddress Class
- The java.net.InetAddress class represents an IP
address. - It converts numeric addresses to host names and
host names to numeric addresses. - It is used by other network classes like Socket
and ServerSocket to identify hosts
10Creating InetAddresses
- There are no public InetAddress() constructors.
Arbitrary addresses may not be created. - All addresses that are created must be checked
with DNS
11The getByName() factory method
- public static InetAddress getByName(String host)
throws UnknownHostException - InetAddress utopia, duke
- try
- utopia InetAddress.getByName("utopia.poly.edu"
) - duke InetAddress.getByName("128.238.2.92")
-
- catch (UnknownHostException e)
- System.err.println(e)
-
12Other ways to create InetAddress objects
- public static InetAddress getAllByName(String
host) throws UnknownHostException - public static InetAddress getLocalHost() throws
UnknownHostException
13Getter Methods
- public boolean isMulticastAddress()
- public String getHostName()
- public byte getAddress()
- public String getHostAddress()
14Utility Methods
- public int hashCode()
- public boolean equals(Object o)
- public String toString()
15Ports
- In general a host has only one Internet address
- This address is subdivided into 65,536 ports
- Ports are logical abstractions that allow one
host to communicate simultaneously with many
other hosts - Many services run on well-known ports. For
example, http tends to run on port 80
16Protocols
- A protocol defines how two hosts talk to each
other. - The daytime protocol, RFC 867, specifies an ASCII
representation for the time that's legible to
humans. - The time protocol, RFC 868, specifies a binary
representation, for the time that's legible to
computers. - There are thousands of protocols, standard and
non-standard
17IETF RFCs
- Requests For Comment
- Document how much of the Internet works
- Various status levels from obsolete to required
to informational - TCP/IP, telnet, SMTP, MIME, HTTP, and more
- http//www.faqs.org/rfc/
18W3C Standards
- IETF is based on rough consensus and running
code - W3C tries to run ahead of implementation
- IETF is an informal organization open to
participation by anyone - W3C is a vendor consortium open only to companies
19W3C Standards
- HTTP
- HTML
- XML
- RDF
- MathML
- SMIL
- P3P
20URLs
- A URL, short for "Uniform Resource Locator", is a
way to unambiguously identify the location of a
resource on the Internet.
21Example URLs
- http//java.sun.com/
- file///Macintosh20HD/Java/Docs/JDK201.1.120doc
s/api/java.net.InetAddress.html_top_ - http//www.macintouch.com80/newsrecent.shtml
- ftp//ftp.info.apple.com/pub/
- mailtoelharo_at_metalab.unc.edu
- telnet//utopia.poly.edu
- ftp//mp3mp3_at_138.247.121.6121000/c3a/stuff/mp3/
- http//elharo_at_java.oreilly.com/
- http//metalab.unc.edu/nywc/comps.phtml?categoryC
horalWorks
22The Pieces of a URL
- the protocol, aka scheme
- the authority
- user info
- user name
- password
- host name or address
- port
- the path, a.k.a. file
- the ref, a.k.a. section or anchor
- the query string
23The java.net.URL class
- A URL object represents a URL.
- The URL class contains methods to
- create new URLs
- parse the different parts of a URL
- get an input stream from a URL so you can read
data from a server - get content from the server as a Java object
24Content and Protocol Handlers
- Content and protocol handlers separate the data
being downloaded from the the protocol used to
download it. - The protocol handler negotiates with the server
and parses any headers. It gives the content
handler only the actual data of the requested
resource. - The content handler translates those bytes into a
Java object like an InputStream or ImageProducer.
25Finding Protocol Handlers
- When the virtual machine creates a URL object, it
looks for a protocol handler that understands the
protocol part of the URL such as "http" or
"mailto". - If no such handler is found, the constructor
throws a MalformedURLException.
26Supported Protocols
- The exact protocols that Java supports vary from
implementation to implementation though http and
file are supported pretty much everywhere. Sun's
JDK 1.1 understands ten - file
- ftp
- gopher
- http
- mailto
- appletresource
- doc
- netdoc
- systemresource
- verbatim
27URL Constructors
- There are four (six in 1.2) constructors in the
java.net.URL class. - public URL(String u) throws MalformedURLException
- public URL(String protocol, String host, String
file) throws MalformedURLException - public URL(String protocol, String host, int
port, String file) throws MalformedURLException - public URL(URL context, String url) throws
MalformedURLException - public URL(String protocol, String host, int
port, String file, URLStreamHandler handler)
throws MalformedURLException - public URL(URL context, String url,
URLStreamHandler handler) throws
MalformedURLException
28Constructing URL Objects
- An absolute URL like http//www.poly.edu/fall97/gr
ad.htmlcs - try
- URL u new URL( "http//www.poly.edu/fall97/grad
.htmlcs") -
- catch (MalformedURLException e)
29Constructing URL Objects in Pieces
- You can also construct the URL by passing its
pieces to the constructor, like this - URL u null
- try
- u new URL("http", "www.poly.edu",
"/schedule/fall97/bgrad.htmlcs") -
- catch (MalformedURLException e)
30Including the Port
- URL u null
- try
- u new URL("http", "www.poly.edu", 8000,
"/fall97/grad.htmlcs") -
- catch (MalformedURLException e)
31Relative URLs
- Many HTML files contain relative URLs.
- Consider the page http//metalab.unc.edu/javafaq/i
ndex.html - On this page a link to books.html" refers to
http//metalab.unc.edu/javafaq/books.html.
32Constructing Relative URLs
- The fourth constructor creates URLs relative to a
given URL. For example, - try
- URL u1 new URL("http//metalab.unc.edu/index.h
tml") - URL u2 new URL(u1, "books.html")
-
- catch (MalformedURLException e)
- This is particularly useful when parsing HTML.
33Parsing URLs
- The java.net.URL class has five methods to split
a URL into its component parts. These are - public String getProtocol()
- public String getHost()
- public int getPort()
- public String getFile()
- public String getRef()
34For example,
- try
- URL u new URL("http//www.poly.edu/fall97/grad
.htmlcs ") - System.out.println("The protocol is "
u.getProtocol()) - System.out.println("The host is "
u.getHost()) - System.out.println("The port is "
u.getPort()) - System.out.println("The file is "
u.getFile()) - System.out.println("The anchor is "
u.getRef()) -
- catch (MalformedURLException e)
35Parsing URLs
- JDK 1.3 adds three more
- public String getAuthority()
- public String getUserInfo()
- public String getQuery()
36Missing Pieces
- If a port is not explicitly specified in the URL
it's set to -1. This means the default port. - If the ref doesn't exist, it's just null, so
watch out for NullPointerExceptions. Better yet,
test to see that it's non-null before using it. - If the file is left off completely, e.g.
http//java.sun.com, then it's set to "/".
37Reading Data from a URL
- The openStream() method connects to the server
specified in the URL and returns an InputStream
object fed by the data from that connection. - public final InputStream openStream() throws
IOException - Any headers that precede the actual data are
stripped off before the stream is opened. - Network connections are less reliable and slower
than files. Buffer with a BufferedReader or a
BufferedInputStream.
38Webcat
- import java.net.
- import java.io.
- public class Webcat
- public static void main(String args)
- for (int i 0 i lt args.length i)
- try
- URL u new URL(argsi)
- InputStream in u.openStream()
- InputStreamReader isr new
InputStreamReader(in) - BufferedReader br new BufferedReader(isr)
- String theLine
- while ((theLine br.readLine()) ! null)
- System.out.println(theLine)
-
- catch (IOException e) System.err.println(e
) -
-
39The Bug in readLine()
- What readLine() does
- Sees a carriage return, waits to see if next
character is a line feed before returning - What readLine() should do
- Sees a carriage return, return, throw away next
character if it's a linefeed
40Webcat
- import java.net.
- import java.io.
- public class Webcat
- public static void main(String args)
- for (int i 0 i lt args.length i)
- try
- URL u new URL(argsi)
- InputStream in u.openStream()
- InputStreamReader isr new
InputStreamReader(in) - BufferedReader br new BufferedReader(isr)
- int c
- while ((c br.read()) ! -1)
- System.out.write(c)
-
- catch (IOException e) System.err.println(e
) -
-
41CGI
- Common Gateway Interface
- A lot is written about writing server side CGI.
Im going to show you client side CGI. - Well need to explore HTTP a little deeper to do
this
42Normal web surfing uses these two steps
- The browser requests a page
- The server sends the page
- Data flows primarily from the server to the
client.
43Forms
- There are times when the server needs to get data
from the client rather than the other way around.
The common way to do this is with a form like
this one
44CGI
- The user types data into a form and hits the
submit button. - The browser sends the data to the server using
the Common Gateway Interface, CGI. - CGI uses the HTTP protocol to transmit the data,
either as part of the query string or as separate
data following the MIME header.
45GET and POST
- When the data is sent as a query string included
with the file request, this is called CGI GET. - When the data is sent as data attached to the
request following the MIME header, this is called
CGI POST
46HTTP
- Web browsers communicate with web servers through
a standard protocol known as HTTP, an acronym for
HyperText Transfer Protocol. - This protocol defines
- how a browser requests a file from a web server
- how a browser sends additional data along with
the request (e.g. the data formats it can
accept), - how the server sends data back to the client
- response codes
47A Typical HTTP Connection
- Client opens a socket to port 80 on the server.
- Client sends a GET request including the name and
path of the file it wants and the version of the
HTTP protocol it supports. - The client sends a MIME header.
- The client sends a blank line.
- The server sends a MIME header
- The server sends the data in the file.
- The server closes the connection.
48What the client sends to the server
- GET /javafaq/images/cup.gif HTTP/1.0
- Connection Keep-Alive
- User-Agent Mozilla/3.01 (Macintosh I PPC)
- Host www.oreilly.com80
- Accept image/gif, image/x-xbitmap, image/jpeg,
/
49MIME
- MIME is an acronym for "Multipurpose Internet
Mail Extensions". - an Internet standard defined in RFCs 2045 through
2049 - originally intended for use with email messages,
but has been been adopted for use in HTTP.
50Browser Request MIME Header
- When the browser sends a request to a web server,
it also sends a MIME header. - MIME headers contain name-value pairs,
essentially a name followed by a colon and a
space, followed by a value. - Connection Keep-Alive
- User-Agent Mozilla/3.01 (Macintosh I PPC)
- Host www.digitalthink.com80
- Accept image/gif, image/x-xbitmap, image/jpeg,
image/pjpeg, /
51Server Response MIME Header
- When a web server responds to a web browser it
sends a response message and a MIME header along
with the response that looks something like this - HTTP/1.0 200 OK
- Server Netscape-Enterprise/2.01
- Date Sat, 02 Aug 1997 075246 GMT
- Accept-ranges bytes
- Last-modified Tue, 29 Jul 1997 150646 GMT
- Content-length 2810
- Content-type text/html
52Query Strings
- CGI GET data is sent in URL encoded query strings
- a query string is a set of namevalue pairs
separated by ampersands - AuthorSadie, JulieTitleWomen Composers
- separated from rest of URL by a question mark
53URL Encoding
- Alphanumeric ASCII characters (a-z, A-Z, and 0-9)
and the -_.!'(), punctuation symbols are left
unchanged. - The space character is converted into a plus sign
(). - Other characters (e.g. , , , , , , , and
so on) are translated into a percent sign
followed by the two hexadecimal digits
corresponding to their numeric value.
54For example,
- The comma is ASCII character 44 (decimal) or 2C
(hex). Therefore if the comma appears as part of
a URL it is encoded as 2C. - The query string "AuthorSadie, JulieTitleWomen
Composers" is encoded as - AuthorSadie2CJulieTitleWomenComposers
55The URLEncoder class
- The java.net.URLEncoder class contains a single
static method which encodes strings in
x-www-form-url-encoded format - URLEncoder.encode(String s)
56For example,
- String qs "AuthorSadie, JulieTitleWomen
Composers" - String eqs URLEncoder.encode(qs)
- System.out.println(eqs)
- This prints
- Author3dSadie2cJulie26Title3dWomenComposers
57- String eqs "Author" URLEncoder.encode("Sadie,
Julie") - eqs ""
- eqs "Title"
- eqs URLEncoder.encode("Women Composers")
- This prints the properly encoded query string
- AuthorSadie2cJulieTitleWomenComposers
58The URLDecoder class
- In Java 1.2 the java.net.URLDecoder class
contains a single static method which decodes
strings in x-www-form-url-encoded format - URLEncoder.decode(String s)
59GET URLs
- String eqs
- "Author" URLEncoder.encode("Sadie, Julie")
- eqs ""
- eqs "Title"
- eqs URLEncoder.encode("Women Composers")
- try
- URL u new URL("http//www.superbooks.com/sea
rch.cgi?" eqs) - InputStream in u.openStream()
- //...
-
- catch (IOException e) //...
60URLConnections
- The java.net.URLConnection class is an abstract
class that handles communication with different
kinds of servers like ftp servers and web
servers. - Protocol specific subclasses of URLConnection
handle different kinds of servers. - By default, connections to HTTP URLs use the GET
method.
61URLConnections vs. URLs
- Can send output as well as read input
- Can post data to CGIs
- Can read headers from a connection
62URLConnection five steps
- 1. The URL is constructed.
- 2. The URLs openConnection() method creates the
URLConnection object. - 3. The parameters for the connection and the
request properties that the client sends to the
server are set up. - 4. The connect() method makes the connection to
the server. (optional) - 5. The response header information is read using
getHeaderField().
63I/O Across a URLConnection
- Data may be read from the connection in one of
two ways - raw by using the input stream returned by
getInputStream() - through a content handler with getContent().
- Data can be sent to the server using the output
stream provided by getOutputStream().
64For example,
- try
- URL u new URL("http//www.wwwac.org/")
- URLConnection uc u.openConnection()
- uc.connect()
- InputStream in uc.getInputStream()
- // read the data...
-
- catch (IOException e) //...
65Reading Header Data
- The getHeaderField(String name) method returns
the string value of a named header field. - Names are case-insensitive.
- If the requested field is not present, null is
returned. - String lm uc.getHeaderField("Last-modified")
66getHeaderFieldKey()
- The keys of the header fields are returned by the
getHeaderFieldKey(int n) method. - The first field is 1.
- If a numbered key is not found, null is returned.
- You can use this in combination with
getHeaderField() to loop through the complete
header
67For example
- String key null
- for (int i1 (key uc.getHeaderFieldKey(i))!nul
l) i) - System.out.println(key " "
uc.getHeaderField(key))
68getHeaderFieldInt() and getHeaderFieldDate()
- Utility methods that read a named header and
convert its value into an int and a long
respectively. - public int getHeaderFieldInt(String name, int
default) - public long getHeaderFieldDate(String name, long
default)
69- The long returned by getHeaderFieldDate() can be
converted into a Date object using a Date()
constructor like this - long lm uc.getHeaderFieldDate("Last-modified",
0) - Date lastModified new Date(lm)
70Six Convenience Methods
- These return the values of six particularly
common header fields - public int getContentLength()
- public String getContentType()
- public String getContentEncoding()
- public long getExpiration()
- public long getDate()
- public long getLastModified()
71- try
- URL u new URL("http//www.sdexpo.com/")
- URLConnection uc u.openConnection()
- uc.connect()
- String keynull
- for (int n 1
- (keyuc.getHeaderFieldKey(n)) ! null
- n)
- System.out.println(key " "
uc.getHeaderField(key)) -
-
- catch (IOException e)
- System.err.println(e)
-
72Writing data to a URLConnection
- Similar to reading data from a URLConnection.
- First inform the URLConnection that you plan to
use it for output - Before getting the connection's input stream, get
the connection's output stream and write to it. - Commonly used to talk to CGIs that use the POST
method
73Eight Steps
- 1. Construct the URL.
- 2. Call the URLs openConnection() method to
create the URLConnection object. - 3. Pass true to the URLConnections setDoOutput()
method - 4. Create the data you want to send, preferably
as a byte array.
74- 5. Call getOutputStream() to get an output stream
object. - 6. Write the byte array calculated in step 5 onto
the stream. - 7. Close the output stream.
- 8. Call getInputStream() to get an input stream
object. Read from it as usual.
75POST CGIs
- A typical POST request to a CGI looks like this
- POST /cgi-bin/booksearch.pl HTTP/1.0
- Referer http//www.macfaq.com/sampleform.html
- User-Agent Mozilla/3.01 (Macintosh I PPC)
- Content-length 60
- Content-type text/x-www-form-urlencoded
- Host utopia.poly.edu56435
- usernameSadie2CJulierealnameWomenComposers
76A POST request includes
- the POST line
- a MIME header which must include
- content type
- content length
- a blank line that signals the end of the MIME
header - the actual data of the form, encoded in
x-www-form-urlencoded format.
77- A URLConnection for an http URL will set up the
request line and the MIME header for you as long
as you set its doOutput field to true by invoking
setDoOutput(true). - If you also want to read from the connection, you
should set doInput to true with setDoInput(true)
too.
78For example,
- URLConnection uc u.openConnection()
- uc.setDoOutput(true)
- uc.setDoInput(true)
79- The request line and MIME header are sent as
soon as the URLConnection connects. Then
getOutputStream() returns an output stream on
which you can write the x-www-form-urlencoded
name-value pairs.
80HttpURLConnection
- java.net.HttpURLConnection is an abstract
subclass of URLConnection that provides some
additional methods specific to the HTTP protocol.
- URL connection objects that are returned by an
http URL will be instances of java.net.HttpURLConn
ection.
81Recall
- a typical HTTP response from a web server begins
like this - HTTP/1.0 200 OK
- Server Netscape-Enterprise/2.01
- Date Sat, 02 Aug 1997 075246 GMT
- Accept-ranges bytes
- Last-modified Tue, 29 Jul 1997 150646 GMT
- Content-length 2810
- Content-type text/html
82Response Codes
- The getHeaderField() and getHeaderFieldKey()
don't return the HTTP response code - After you've connected, you can retrieve the
numeric response code--200 in the above
example--with the getResponseCode() method and
the message associated with it--OK in the above
example--with the getResponseMessage() method.
83HTTP Protocols
- Java 1.0 only supports GET and POST requests to
HTTP servers - Java 1.1/1.2 supports GET, POST, HEAD, OPTIONS,
PUT, DELETE, and TRACE. - The protocol is chosen with the
setRequestMethod(String method) method. - A java.net.ProtocolException, a subclass of
IOException, is thrown if an unknown protocol is
specified.
84getRequestMethod()
- The getRequestMethod() method returns the string
form of the request method currently set for the
URLConnection. GET is the default method.
85disconnect()
- The disconnect() method of the HttpURLConnection
class closes the connection to the web server. - Needed for HTTP/1.1 Keep-alive
86For example,
- try
- URL u new URL( "http//www.metalab.unc.edu/jav
afaq/books.html" ) - HttpURLConnection huc (HttpURLConnection)
u.openConnection() - huc.setRequestMethod("PUT")
- huc.connect()
- OutputStream os huc.getOutputStream()
- int code huc.getResponseCode()
- if (code gt 200 lt 300)
- // put the data...
-
- huc.disconnect()
-
- catch (IOException e) //...
87usingProxy
- The boolean usingProxy() method returns true if
web connections are being funneled through a
proxy server, false if they're not.
88Redirect Instructions
- Most web servers can be configured to
automatically redirect browsers to the new
location of a page that's moved. - To redirect browsers, a server sends a 300 level
response and a Location header that specifies the
new location of the requested page.
89- GET /elharo/macfaq/index.html HTTP/1.0
- HTTP/1.1 302 Moved Temporarily
- Date Mon, 04 Aug 1997 142127 GMT
- Server Apache/1.2b7
- Location http//www.macfaq.com/macfaq/index.html
- Connection close
- Content-type text/html
- ltHTMLgtltHEADgt
- ltTITLEgt302 Moved Temporarilylt/TITLEgt
- lt/HEADgtltBODYgt
- ltH1gtMoved Temporarilylt/H1gt
- The document has moved ltA HREF"http//www.macfaq.
com/macfaq/index.html"gtherelt/Agt.ltPgt - lt/BODYgtlt/HTMLgt
90- HTML is returned for browsers that don't
understand redirects, but most modern browsers
jump straight to the page specified in the
Location header instead. - Because redirects can change the site which a
user is connecting without their knowledge so
redirects are not arbitrarily followed by
URLConnections.
91Following Redirects
- HttpURLConnection.setFollowRedirects(true) method
says that connections will follow redirect
instructions from the web server. - Untrusted applets are not allowed to set this.
- HttpURLConnection.getFollowRedirects() returns
true if redirect requests are honored, false if
they're not.
92Datagrams
- Before data is sent across the Internet from one
host to another using TCP/IP, it is split into
packets of varying but finite size called
datagrams. - Datagrams range in size from a few dozen bytes to
about 60,000 bytes. - Packets larger than this, and often smaller than
this, must be split into smaller pieces before
they can be transmitted.
93Packets Allow Error Correction
- If one packet is lost, it can be retransmitted
without requiring redelivery of all other
packets. - If packets arrive out of order they can be
reordered at the receiving end of the connection.
94Abstraction
- Datagrams are mostly hidden from the Java
programmer. - The host's native networking software
transparently splits data into packets on the
sending end of a connection, and then reassembles
packets on the receiving end. - Instead, the Java programmer is presented with a
higher level abstraction called a socket.
95Sockets
- A socket is a reliable connection for the
transmission of data between two hosts. - Sockets isolate programmers from the details of
packet encodings, lost and retransmitted packets,
and packets that arrive out of order. - There are limits. Sockets are more likely to
throw IOExceptions than files, for example.
96Socket Operations
- There are four fundamental operations a socket
performs. These are - 1. Connect to a remote machine
- 2. Send data
- 3. Receive data
- 4. Close the connection
- A socket may not be connected to more than one
host at a time. - A socket may not reconnect after it's closed.
97The java.net.Socket class
- The java.net.Socket class allows you to create
socket objects that perform all four fundamental
socket operations. - You can connect to remote machines you can send
data you can receive data you can close the
connection. - Each Socket object is associated with exactly one
remote host. To connect to a different host, you
must create a new Socket object.
98Constructing a Socket
- Connection is accomplished through the
constructors. - public Socket(String host, int port) throws
UnknownHostException, IOException - public Socket(InetAddress address, int port)
throws IOException - public Socket(String host, int port, InetAddress
localAddr, int localPort) throws IOException - public Socket(InetAddress address, int port,
InetAddress localAddr, int localPort) throws
IOException
99Opening Sockets
- The Socket() constructors do not just create a
Socket object. They also attempt to connect the
underlying socket to the remote server. - All the constructors throw an IOException if the
connection can't be made for any reason.
100- You must at least specify the remote host and
port to connect to. - The host may be specified as either a string like
"utopia.poly.edu" or as an InetAddress object. - The port should be an int between 1 and 65535.
- Socket webMetalab new Socket("metalab.unc.edu",
80)
101- You cannot just connect to any port on any host.
The remote host must actually be listening for
connections on that port. - You can use the constructors to determine which
ports on a host are listening for connections.
102- public static void scan(InetAddress remote)
- String hostname remote.getHostName()
- for (int port 0 port lt 65536 port)
- try
- Socket s new Socket(remote, port)
- System.out.println("There is a server on
port " - port " of " hostname)
- s.close()
-
- catch (IOException e)
- // The remote host is not listening on
this port -
-
-
103Picking an IP address
- The last two constructors also specify the host
and port you're connecting from. - On a system with multiple IP addresses, like many
web servers, this allows you to pick your network
interface and IP address.
104Choosing a Local Port
- You can also specify a local port number,
- Setting the port to 0 tells the system to
randomly choose an available port. - If you need to know the port you're connecting
from, you can always get it with getLocalPort(). - Socket webMetalab new Socket("metalab.unc.edu",
80, "calzone.oit.unc.edu", 0)
105Sending and Receiving Data
- Data is sent and received with output and input
streams. - There are methods to get an input stream for a
socket and an output stream for the socket. - public InputStream getInputStream() throws
IOException - public OutputStream getOutputStream() throws
IOException - There's also a method to close a socket.
- public synchronized void close() throws
IOException
106Reading Input from a Socket
- The getInputStream() method returns an
InputStream which reads data from the socket. - You can use all the normal methods of the
InputStream class to read this data. - Most of the time you'll chain the input stream
to some other input stream or reader object to
more easily handle the data.
107For example
- The following code fragment connects to the
daytime server on port 13 of metalab.unc.edu, and
displays the data it sends. - try
- Socket s new Socket("metalab.unc.edu", 13)
- InputStream in s.getInputStream()
- InputStreamReader isr new InputStreamReader(in
) - BufferedReader br new BufferedReader(isr)
- String theTime br.readLine()
- System.out.println(theTime)
-
- catch (IOException e)
- return (new Date()).toString()
108Writing Output to a Socket
- The getOutputStream() method returns an output
stream which writes data to the socket. - Most of the time you'll chain the raw output
stream to some other output stream or writer
class to more easily handle the data.
109Discard
- byte b new byte128
- try
- Socket s new Socket("metalab.unc.edu", 9)
- OutputStream theOutput s.getOutputStream()
- while (true)
- int n theInput.available()
- if (n gt b.length) n b.length
- int m theInput.read(b, 0, n)
- if (m -1) break
- theOutput.write(b, 0, n)
-
- s.close()
-
- catch (IOException e)
110Reading and Writing to a Socket
- It's unusual to only read from a socket. It's
even more unusual to only write to a socket. - Most protocols require the client to both read
and write.
111- Some protocols require the reads and the writes
to be interlaced. That is - write
- read
- write
- read
- write
- read
112- Other protocols, such as HTTP 1.0, have multiple
writes, followed by multiple reads, like this - write
- write
- write
- read
- read
- read
- read
113- Other protocols don't care and allow client
requests and server responses to be freely
intermixed. - Java places no restrictions on reading and
writing to sockets. - One thread can read from a socket while another
thread writes to the socket at the same time.
114- try
- URL u new URL(argsi)
- if (u.getPort() ! -1) port u.getPort()
- if (!(u.getProtocol().equalsIgnoreCase("http")))
- System.err.println("I only understand
http.") -
- Socket s new Socket(u.getHost(),
u.getPort()) - OutputStream theOutput s.getOutputStream()
- PrintWriter pw new PrintWriter(theOutput,
false) - pw.print("GET " u.getFile() "
HTTP/1.0\r\n") - pw.print("Accept text/plain, text/html,
text/\r\n") - pw.print("\r\n")
- pw.flush()
- InputStream in s.getInputStream()
- InputStreamReader isr new InputStreamReader(in
) - BufferedReader br new BufferedReader(isr)
- int c
- while ((c br.read()) ! -1)
- System.out.write(c)
115Socket Options
- Several methods set various socket options. Most
of the time the defaults are fine. - public void setTcpNoDelay(boolean on) throws
SocketException - public boolean getTcpNoDelay() throws
SocketException - public void setSoLinger(boolean on, int val)
throws SocketException - public int getSoLinger() throws SocketException
- public synchronized void setSoTimeout(int
timeout) throws SocketException - public synchronized int getSoTimeout() throws
SocketException
116- These methods to return information about the
socket - public InetAddress getInetAddress()
- public InetAddress getLocalAddress()
- public int getPort()
- public int getLocalPort()
- Finally there's the usual toString() method
- public String toString()
117Servers
- There are two ends to each connection the
client, that is the host that initiates the
connection, and the server, that is the host that
responds to the connection. - Clients and servers are connected by sockets.
- A server, rather than connecting to a remote
host, a program waits for other hosts to connect
to it.
118Server Sockets
- A server socket binds to a particular port on the
local machine. - Once it has successfully bound to a port, it
listens for incoming connection attempts. - When a server detects a connection attempt, it
accepts the connection. This creates a socket
between the client and the server over which the
client and the server communicate.
119Multiple Clients
- Multiple clients can connect to the same port on
the server at the same time. - Incoming data is distinguished by the port to
which it is addressed and the client host and
port from which it came. - The server can tell for which service (like http
or ftp) the data is intended by inspecting the
port. - It can tell which open socket on that service the
data is intended for by looking at the client
address and port stored with the data.
120Queueing
- Incoming connections are stored in a queue until
the server can accept them. - On most systems the default queue length is
between 5 and 50. - Once the queue fills up further incoming
connections are refused until space in the queue
opens up.
121The java.net.ServerSocket Class
- The java.net.ServerSocket class represents a
server socket. - A ServerSocket object is constructed on a
particular local port. Then it calls accept() to
listen for incoming connections. - accept() blocks until a connection is detected.
Then accept() returns a java.net.Socket object
that performs the actual communication with the
client.
122Constructors
- There are three constructors that let you specify
the port to bind to, the queue length for
incoming connections, and the IP address to bind
to - public ServerSocket(int port) throws IOException
- public ServerSocket(int port, int backlog) throws
IOException - public ServerSocket(int port, int backlog,
InetAddress networkInterface) throws IOException
123Constructing Server Sockets
- Normally you only specify the port you want to
listen on, like this - try
- ServerSocket ss new ServerSocket(80)
-
- catch (IOException e)
- System.err.println(e)
-
124- When a ServerSocket object is created, it
attempts to bind to the port on the local host
given by the port argument. - If another server socket is already listening to
the port, then a java.net.BindException, a
subclass of IOException, is thrown. - No more than one process or thread can listen to
a particular port at a time. This includes
non-Java processes or threads. - For example, if there's already an HTTP server
running on port 80, you won't be able to bind to
port 80.
125- On Unix systems (but not Windows or the Mac) your
program must be running as root to bind to a port
between 1 and 1023. - 0 is a special port number. It tells Java to pick
an available port. - The getLocalPort() method tells you what port the
server socket is listening on. This is useful if
the client and the server have already
established a separate channel of communication
over which the chosen port number can be
communicated. - FTP
126Expanding the Queue
- If you think you aren't going to be processing
connections very quickly you may wish to expand
the queue when you construct the server socket.
For example, - try
- ServerSocket httpd new ServerSocket(80, 50)
-
- catch (IOException e)
- System.err.println(e)
127Choosing an IP address
- Many hosts have more than one IP address.
- By default, a server socket binds to all
available IP addresses on a given port. - You can modify that behavior with this
constructor -
- public ServerSocket(int port, int backlog,
InetAddress bindAddr)throws IOException
128Example
- try
- InetAddress ia InetAddress.getByName("199.1.32
.90") - ServerSocket ss new ServerSocket(80, 50, ia)
-
- catch (IOException e)
- System.err.println(e)
129- On a server with multiple IP addresses, the
getInetAddress() method tells you which one this
server socket is listening to. - public InetAddress getInetAddress()
- The getLocalPort() method tells you which port
you're listening to. - public int getLocalPort()
130- The accept() and close() methods provide the
basic functionality of a server socket. - public Socket accept() throws IOException
- public void close() throws IOException
- A server socket cant be reopened after its
closed
131Reading Data with a ServerSocket
- ServerSocket objects use their accept() method to
connect to a client. - public Socket accept() throws IOException
- There are no getInputStream() or
getOutputStream() methods for ServerSocket. - accept() returns a Socket object, and its
getInputStream() and getOutputStream() methods
provide streams.
132Example
- try
- ServerSocket ss new ServerSocket(2345)
- Socket s ss.accept()
- PrintWriter pw new
- PrintWriter(s.getOutputStream())
- pw.println("Hello There!")
- pw.println("Goodbye now.")
- s.close()
-
- catch (IOException e)
- System.err.println(e)
133Better Example
- try
- ServerSocket ss new ServerSocket(2345)
- Socket s ss.accept()
- PrintWriter pw new
- PrintWriter(s.getOutputStream())
- pw.print("Hello There!\r\n")
- pw.print("Goodbye now.\r\n")
- s.close()
-
- catch (IOException e)
- System.err.println(e)
134Writing Data to a Client
- try
- ServerSocket ss new ServerSocket(port)
- while (true)
- try
- Socket s ss.accept()
- PrintWriter pw new PrintWriter(s.getOutputSt
ream()) - pw.print("Hello " s.getInetAddress() " on
port " - s.getPort() "\r\n")
- pw.print("This is " s.getLocalAddress() "
on port " - s.getLocalPort() "\r\n")
- pw.flush()
- s.close()
-
- catch (IOException e)
-
-
- catch (IOException e) System.err.println(e)
135Interacting with a Client
- More commonly, a server needs to both read a
client request and write a response.
136Threading
- No more than one server socket can listen to a
particular port at one time. - Since a server may need to handle many
connections at once, server programs tend to be
heavily multi-threaded. - Generally the server socket passes off the actual
processing of connections to a separate thread.
137Adding Threading to a Server
- It's better to make your server multi-threaded.
- There should be a loop which continually accepts
new connections. - Rather than handling the connection directly the
socket should be passed to a Thread object that
handles the connection.
138Adding a Thread Pool to a Server
- Multi-threading is a good thing but it's still
not a perfect solution. - Look at this accept loop
- while (true)
- try
- Socket s ss.accept()
- ThreadedEchoServer tes new ThreadedEchoServer(
s) tes.start() -
- catch (IOException e)
139- Every pass through this loop, a new thread gets
created. Every time a connection is finished the
thread is disposed of. - Spawning a new thread for each connection takes a
non-trivial amount of time, especially on a
heavily loaded server. - Too many simultaneous threads overload a VM.
140Thread Pools
- Create a pool of threads when the server
launches, store incoming connections in a queue,
and have the threads in the pool progressively
remove connections from the queue and process
them. - The main change you need to make to implement
this is to call accept() in the run() method
rather than in the main() method.
141Setting Server Socket Options
- There are three methods to set and get various
options. The defaults are generally fine. - public synchronized void setSoTimeout(int
timeout) throws SocketException - public synchronized int getSoTimeout() throws
IOException - public static synchronized void
setSocketFactory(SocketImplFactory fac) throws
IOException
142Utility Methods
- Finally, there's the usual toString() method
-
- public String toString()
143UDP
- Unreliable Datagram Protocol
- Packet Oriented, not stream oriented like TCP/IP
- Much faster but no error correction
- NFS, TFTP, and FSP use UDP/IP
- Must fit data into packets of about 8K or less
144The UDP Classes
- Java's support for UDP is contained in two
classes - java.net.DatagramSocket
- java.net.DatagramPacket
- A datagram socket is used to send and receive
datagram packets.
145java.net.DatagramPacket
- a wrapper for an array of bytes from which data
will be sent or into which data will be received.
- also contains the address and port to which the
packet will be sent.
146java.net.DatagramSocket
- A DatagramSocket object is a local connection to
a port that does the sending and receiving. - There is no distinction between a UDP socket and
a UDP server socket. - Also unlike TCP sockets, a DatagramSocket can
send to multiple, different addresses. - The address to which data goes is stored in the
packet, not in the socket.
147UDP ports
- Separate from TCP ports.
- Each computer has 65,536 UDP ports as well as its
65,536 TCP ports. - A server socket can be bound to TCP port 20 at
the same time as a datagram socket is bound to
UDP port 20.
148Two DatagramPacket Constructors
- public DatagramPacket(byte data, int length)
- public DatagramPacket(byte data, int length,
InetAddress remote, int port) - First is for receiving, second is for sending
149For example,
- String s "My first UDP Packet"
- byte b s.getBytes()
- DatagramPacket dp new DatagramPacket(b,
b.length)
150With a destination
- try
- InetAddress metalab InetAddress.getByName("meta
lab.unc.edu") - int chargen 19
- String s "My second UDP Packet"
- byte b s.getBytes()
- DatagramPacket dp new DatagramPacket(b,
b.length, metalab, chargen) -
- catch (UnknownHostException e)
- System.err.println(e)
151DatagramPackets are not immutable.
- public synchronized void setAddress(InetAddress
remote) - public synchronized void setPort(int port)
- public synchronized void setData(byte data)
- public synchronized void setLength(int length)
- public synchronized InetAddress getAddress()
- public synchronized int getPort()
- public synchronized byte getData()
- public synchronized int getLength()
- These methods are primarily useful when you're
receiving datagrams.
152java.net.DatagramSocket
- public DatagramSocket() throws SocketException
- public DatagramSocket(int port) throws
SocketException - public DatagramSocket(int port, InetAddress
laddr) throws SocketException - The first is for client datagram sockets that is
sockets that send datagrams before receiving any.
- The second two are for server datagram sockets
since they specify the port and optionally the IP
address of the socket
153Sending UDP Datagrams
- To send data to a particular server
- Convert the data into byte array.
- Pass this byte array, the length of the data in
the array (most of the time this will be the
length of the array) and the InetAddress and port
to which you wish to send it into the
DatagramPacket() constructor. - Next create a DatagramSocket and pass the packet
to its send() method
154For example,
- InetAddress metalab InetAddress.getByName("metal
ab.unc.edu") - int chargen 19
- String s "My second UDP Packet"
- byte b s.getBytes()
- DatagramPacket dp new DatagramPacket(b,
b.length, ia, chargen) - DatagramSocket sender new DatagramSocket()
- sender.send(dp)
155Receiving UDP Datagrams
- Construct a DatagramSocket object on the port on
which you want to listen. - Pass an empty DatagramPacket object to the
DatagramSocket's receive() method. - public synchronized void receive(DatagramPacket
dp) throws IOException - The calling thread blocks until a datagram is
received.
156 - dp is filled with the data from that datagram.
- Use getPort() and and getAddress() to tell where
the packet came from, getData() to retrieve the
data, and getLength() to see how many bytes were
in the data. - If the received packet was too long for the
buffer, it's truncated to the length of the
buffer. - Length is reset when packet is received
157For example,
- try
- byte buffer new byte65536
- DatagramPacket incoming new
DatagramPacket(buffer, buffer.length) - DatagramSocket ds new DatagramSocket(2134)
- ds.receive(incoming)
- byte data incoming.getData()
- String s new String(data, 0,
data.getLength()) - System.out.println("Port " incoming.getPort()
" on " incoming.getAddress() " sent this
message") - System.out.println(s)
-
- catch (IOException e)
- System.err.println(e)
158Receiving Multiple Packets
- Watch out for strictly decreasing packet sizes
- DatagramPacket incoming new DatagramPacket(new
byte8192, 8192) - DatagramSocket ds new DatagramSocket(2134)
- while (true)
- try
- incoming.setLength(8192)
- ds.receive(incoming)
- byte data incoming.getData()
- String s new String(data, 0,
data.getLength()) - System.out.println("Port "
incoming.getPort() - " on " incoming.getAddress()
- " sent this message")
- System.out.println(s)
-
- catch (IOException e)
- System.err.println(e)
-
159To Learn More
- Java Network Programming
- OReilly Associates, 1997
- ISBN 1-56592-227-1
- Java I/O
- OReilly Associates, 1999
- ISBN 1-56592-485-1
- Web Client Programming with Java
- http//www.digitalthink.com/catalog/cs/cs308/index
.html
160Questions?