24 Java Network Programming Clients
24 Java Network Programming Clients
Network Programming:
Clients
Originals of slides and source code for examples: http://courses.coreservlets.com/Course-Materials/java.html
Also see Java 8 tutorial: http://www.coreservlets.com/java-8-tutorial/ and many other Java EE tutorials: http://www.coreservlets.com/
Customized Java training courses (onsite or at public venues): http://courses.coreservlets.com/java-training.html
For additional materials, please see http://www.coreservlets.com/. The Java tutorial section contains
complete source code for all examples in this tutorial series, plus exercises and exercise solutions for each topic.
Overview
For additional materials, please see http://www.coreservlets.com/. The Java tutorial section contains
complete source code for all examples in this tutorial series, plus exercises and exercise solutions for each topic.
Client vs. Server
• Traditional definition
– Client: User of network services
– Server: Supplier of network services
• Problem with traditional definition
– If there are 2 programs exchanging data, it seems unclear
– Some situations (e.g., X Windows) seem reversed
• Easier way to remember distinction
– Server starts first. Server doesn’t specify host (just port).
– Client starts second. Client specifies host (and port).
• Analogy: Company phone line
– Installing phone is like starting server
– Extension is like port
– Person who calls is the client: he specifies both host (general company number) and
port (extension)
8
9
Confusing Overuse of the Term “Stream”
• InputStream
– Low-level data structure for reading from socket or file or other input source. We
will wrap BufferedReader around it here, and ObjectInputStream around it in later
section.
• OutputStream
– Low-level data structure for sending data to socket or file. We will wrap PrintWriter
around it here, and ObjectOutputStream around it in later section.
• Stream<T> (e.g., Stream<String>)
– High-level wrapper around arrays, Lists, and other data source. Introduced in Java 8
and covered earlier.
• IntStream, DoubleStream, etc.
– Primitive specializations of Java 8 streams. Covered earlier.
10
Using a PrintWriter
• out.printf(formatString, val1, val2, ...);
– Takes String-formatting-template and values (one value for each %blah placeholder)
• See discussion in “Miscellaneous Utilities” section
• Here, “out” will be connected to a Socket instead of referring to standard output
• out.print(string) and out.println(string)
– Take a single String
• String.format(formatString, val1, val2, ...);
– printf outputs a formatted String
out.printf("Blah %s%n", 7);
– String.format returns a formatted String
String s = String.format("Blah %s%n", 7);
out.print(s);
11
Using a BufferedReader
• in.lines()
– Returns a Stream<String>, where each entry in the Stream comes from a separate
line in the input. Generally the most powerful and efficient way to read.
• If socket remains open, you will wait if you try to read to the “end” of the Stream
• See File I/O section for many examples of usage
• in.readLine()
– Returns a single String
• If you are sent a String terminated by end-of-line (CR or CR/LF pair), this returns a
non-null String
• If the socket is closed, this returns null
• If socket is open but no end-of-line, you will wait
• in.read()
– Returns a single character
12
For additional materials, please see http://www.coreservlets.com/. The Java tutorial section contains
complete source code for all examples in this tutorial series, plus exercises and exercise solutions for each topic.
Big Idea
• Connecting to a server is easy
– Same basic steps every time
• But talking to a server can be hard
– Depending on the protocol that you define, formatting the requests and parsing the
responses may be difficult
• Steps
– Create a Socket
– Attach a PrintWriter to the Socket (for sending data)
– Get a BufferedReader from the socket (for reading data)
– Do I/O (this is only part that changes)
– Close the socket (automatic with try-with-resources)
14
15
Steps for Implementing a Client (Continued)
4. Do I/O
– PrintWriter
• printf or println. Summarized in earlier slide.
– BufferedReader
• lines or readLine. Summarized in earlier slide.
• Notes
– There is standard way to connect to server. There is no standard way to carry on
conversation with server. So, “networking” problems in Java mostly boil down to
String formatting problems (for sending data) and String parsing problems (for
reading data).
– For Java-to-Java communication, things are much simpler because you can use
ObjectInputStream and ObjectOutputStream. See later section on Serialization.
16
client.close();
– If you declare the socket using a try-with-resources, this happens automatically, so you
do not have to call client.close explicitly
– Closing the socket closes the input and output streams as well
17
Exceptions
• UnknownHostException
– If host (passed to constructor) not known to DNS server
• Note that you may use an IP address string for the host
• IOException
– Timeout
– Connection refused by server
– Interruption or other unexpected problem
• Server closing connection does not cause read error: null is returned from “readLine”,
and “lines” simply finishes
• Note
– Socket implements AutoCloseable, so you can use the try-with-resources idea we
first covered in file I/O section
18
try(Socket client = new Socket(...)) { ... }
19
Helper Class: SocketUtils
import java.net.*;
import java.io.*;
A Reusable Network
Client Base Class
Slides © 2016 Marty Hall, hall@coreservlets.com
For additional materials, please see http://www.coreservlets.com/. The Java tutorial section contains
complete source code for all examples in this tutorial series, plus exercises and exercise solutions for each topic.
Idea
• Connecting to server is almost always the same
– Call Socket constructor, use try/catch blocks for UnknownHostException and
IOException, close Socket
• Talking to server is almost always different
– Do I/O with PrintWriter and BufferedReader in protocol-specific manner
• Make reusable NetworkClient class
– Automatically does steps that do not change
– Lets you put in code for the actual I/O (that does change)
• Steps
– Extend NetworkClient
– Override handleConnection(Socket s)
– Instantiate your class and call connect
22
/** Register host and port. Connection is established when you call connect. */
24
Example Client
public class NetworkClientTest extends NetworkClient {
public NetworkClientTest(String host, int port) {
super(host, port);
}
@Override
protected void handleConnection(Socket client) throws IOException {
PrintWriter out = SocketUtils.getWriter(client);
BufferedReader in = SocketUtils.getReader(client);
out.println("Generic Network Client");
System.out.printf ("Generic Network Client:%n" +
"Connected to '%s' and got '%s' in response.%n",
getHost(), in.readLine());
}
25
Example Client (Continued)
public static void main(String[] args) {
String host = "localhost";
int port = 8088;
if (args.length > 0) {
host = args[0];
}
if (args.length > 1) {
port = Integer.parseInt(args[1]);
}
NetworkClientTest tester = new NetworkClientTest(host, port);
tester.connect();
}
}
26
27
coreservlets.com – custom onsite training
Aside: String
Formatting and
Parsing
Slides © 2016 Marty Hall, hall@coreservlets.com
For additional materials, please see http://www.coreservlets.com/. The Java tutorial section contains
complete source code for all examples in this tutorial series, plus exercises and exercise solutions for each topic.
29
Parsing Strings Using StringTokenizer
• Idea
– Build a tokenizer from an initial string
– Retrieve tokens one at a time with nextToken
• A token means a part of the string without the delimeters
– You can also see how many tokens are remaining (countTokens) or simply test if
the number of tokens remaining is nonzero (hasMoreTokens)
30
StringTokenizer
• Constructors
– StringTokenizer(String input, String delimiters)
– StringTokenizer(String input, String delimiters,
boolean includeDelimiters)
– StringTokenizer(String input)
• Default delimiter set is " \t\n\r\f" (whitespace)
• Methods
– nextToken()
– nextToken(String delimiters)
– countTokens()
– hasMoreTokens()
31
Interactive Tokenizer: Example
import java.util.StringTokenizer;
33
Parsing Strings Using the split Method of String
• Basic usage
String[] tokens = mainString.split(regexString);
• Differences from StringTokenizer
– Entire string is the delimiter (not set of 1-char delimiters as with StringTokenizer)
• "foobar".split("ob") returns {"fo", "ar"}
• "foobar".split("bo") returns {"foobar"}
– You can use regular expressions in the delimiter
• ^, $, *, +, ., etc for beginning of String, end of String, 0 or more, 1 or more, any one
character, etc.
• See http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html#sum
– Unless you use "+", an empty string is returned between consecutive delimiters
• "foobar".split("o") returns {"f", "", "bar"}
• "foobar".split("o+") returns {"f", "bar"}
34
– http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html#sum
– http://docs.oracle.com/javase/tutorial/essential/regex/
35
– http://regexr.com/ (Not Java-specific, but very good)
Interactive String Splitter: Example
public class SplitTest {
public static void main(String[] args) {
if (args.length == 2) {
String[] tokens = args[0].split(args[1]);
for(String token: tokens) {
if (token.length() != 0) {
System.out.println(token);
}
}
} else {
System.out.println("Usage: java SplitTest string delimeters");
}
}
}
36
Problems with
Blocking IO
Slides © 2016 Marty Hall, hall@coreservlets.com
For additional materials, please see http://www.coreservlets.com/. The Java tutorial section contains
complete source code for all examples in this tutorial series, plus exercises and exercise solutions for each topic.
39
Using Telnet to Verify Email Addresses
• Example talking to SMTP server
> telnet apl.jhu.edu 25
Trying 128.220.101.100 ...Connected …
220 aplcenmp.apl.jhu.edu Sendmail …
expn hall
250 Marty Hall <hall@aplcenmp.apl.jhu.edu>
expn root
250 Gary Gafke <…>
250 Tom Vellani <…>
quit
221 aplcenmp.apl.jhu.edu closing connection
Connection closed by foreign host.
40
44
Talking to Web
Servers:
General
Slides © 2016 Marty Hall, hall@coreservlets.com
For additional materials, please see http://www.coreservlets.com/. The Java tutorial section contains
complete source code for all examples in this tutorial series, plus exercises and exercise solutions for each topic.
Brief Aside: The HTTP “GET” Command
For URL http://somehost/somepath
HTTP 1.0 HTTP 1.1
Connect to somehost on port 80 Connect to somehost on port 80
GET /somepath HTTP/1.0 GET /somepath HTTP/1.1
Blank line Host: somehost
Connection: close
Blank line
Notes:
• The server closes the connection when it is done sending the page. This makes it easy for Java to read the page: it
can just use lines() and then process the entire Stream<String>, or use readLine() until it gets null.
• The reason for the Host header in HTTP 1.1 is so that you can connect to hosts that are using virtual hosting, i.e.,
sites that host multiple domain names on the same machine. Most small and medium sites use virtual hosting.
• The address after “GET” is called a URI.
• Regarding top-level URLs: for the URL http://somehost, the browser treats it as though it were http://somehost/, and
sends / as the URI for the GET request.
HTTP/1.1 200 OK
...
Connection: close
Content-Type: text/html; charset=ISO-8859-1
<!DOCTYPE HTML>
<html>
...
</html>Connection closed by foreign host.
Unix>
47
Talking to Web Servers Interactively
• Problem
– MS Windows telnet client works poorly for this
• Linux, Solaris, and MacOS telnet clients work fine for this
• Solution: WebClient
– Simple graphical user interface to communicate with HTTP servers
– User can interactively specify:
• URL with host, port, and URI
• HTTP request headers
– HTTP request is performed in a separate thread
– Response document is placed in a scrollable text area
– Download all source files for WebClient from tutorial home page
48
WebClient: Example
49
coreservlets.com – custom onsite training
Talking to Web
Servers:
A Java Client
Slides © 2016 Marty Hall, hall@coreservlets.com
For additional materials, please see http://www.coreservlets.com/. The Java tutorial section contains
complete source code for all examples in this tutorial series, plus exercises and exercise solutions for each topic.
51
Retrieving a URI from a Host
// It is safe to use in.lines() or loop and
// do in.readLine() because Web servers close
// the connection after sending the data.
52
in.lines().forEach(System.out::println);
• Java 7
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
53
Helper Class: Parsing a URL
public class UrlParser {
private String host;
private int port = 80;
private String uri;
55
UrlRetriever in Action
• No explicit port number
HTTP/1.1 200 OK
Server: Apache
...
<!DOCTYPE html>
<html lang=en>
...
<p><b>404.</b> <ins>That’s an error.</ins>
<p>The requested URL <code>/bingSearch</code>
was not found on this server.
<ins>That’s all we know.</ins>
...
57
coreservlets.com – custom onsite training
Talking to Web
Servers:
Using the URL Class
Slides © 2016 Marty Hall, hall@coreservlets.com
For additional materials, please see http://www.coreservlets.com/. The Java tutorial section contains
complete source code for all examples in this tutorial series, plus exercises and exercise solutions for each topic.
60
61
UrlRetriever2 in Action
62
63
Using the URL Methods: Example
public class UrlTest {
public static void main(String[] args) {
if (args.length == 1) {
try {
URL url = new URL(args[0]);
System.out.println
("URL: " + url.toExternalForm() + "\n" +
" File: " + url.getFile() + "\n" +
" Host: " + url.getHost() + "\n" +
" Port: " + url.getPort() + "\n" +
" Protocol: " + url.getProtocol() + "\n" +
" Reference: " + url.getRef());
} catch(MalformedURLException mue) {
System.out.println("Bad URL.");
}
} else
System.out.println("Usage: UrlTest <URL>");
}
}
64
Note: If the port is not explicitly stated in the URL, then the
standard port for the protocol is assumed, and getPort returns –1
65
A Real Browser Using Swing
• The JEditorPane class has builtin support for HTTP and HTML
66
69
coreservlets.com – custom onsite training
Wrap-Up
For additional materials, please see http://www.coreservlets.com/. The Java tutorial section contains
complete source code for all examples in this tutorial series, plus exercises and exercise solutions for each topic.
Summary
• Open a Socket
new Socket("hostname-or-IP-Address", port)
• Get a PrintWriter to use for sending data to server
new PrintWriter(client.getOutputStream(), true)
• Get a BufferedReader to use for reading data from server
new BufferedReader
(new InputStreamReader(client.getInputStream()))
• Notes
– lines and readLine block until data is received or connection is closed
• If connection is closed, lines just completes the Stream and readLine returns null
– HTTP servers normally close the connection after sending data, so it is safe to use
lines or readLine
– String.split and StringTokenizer help parse strings
71
coreservlets.com – custom onsite training
Questions?
More info:
http://courses.coreservlets.com/Course-Materials/java.html – General Java programming tutorial
http://www.coreservlets.com/java-8-tutorial/ – Java 8 tutorial
http://courses.coreservlets.com/java-training.html – Customized Java training courses, at public venues or onsite at your organization
http://coreservlets.com/ – JSF 2, PrimeFaces, Java 7 or 8, Ajax, jQuery, Hadoop, RESTful Web Services, Android, HTML5, Spring, Hibernate, Servlets, JSP, GWT, and other Java EE training
Many additional free tutorials at coreservlets.com (JSF, Android, Ajax, Hadoop, and lots more)
For additional materials, please see http://www.coreservlets.com/. The Java tutorial section contains
complete source code for all examples in this tutorial series, plus exercises and exercise solutions for each topic.