Networking

advertisement
Networking
TCP/IP and the Internet
Sockets in Java
Writing Servers and Clients
Threaded Servers
Identifying and Locating Resources: URIs and URLs
jonas.kvarnstrom@liu.se – 2015

2
The Internet is based on IP, the Internet Protocol (usually v4)
 Low level "send-and-forget" protocol
▪ Send a package; you don't know if it arrived
 32-bit addresses, generally written as 4 bytes: 128.212.201.27
▪ Host names ("www.liu.se") are mapped to IP numbers,
usually via DNS (the Domain Name System)
jonkv@ida
Introduction 1: IP and the Internet

3
jonkv@ida
Introduction 2: IP and the Internet
In Java: Use names directly, or use java.net.InetAddress
 static InetAddress getByName(String host) throws UnknownHostException
 static InetAddress[] getAllByName(String host) throws …
▪
▪
▪
▪
▪
▪
▪
Returns multiple IP addresses for a host
==> www.google.com/173.194.32.243
==> www.google.com/173.194.32.240
==> www.google.com/173.194.32.241
==> www.google.com/173.194.32.242
==> www.google.com/173.194.32.244
==> www.google.com/2a00:1450:4008:801:0:0:0:1010
 static InetAddress getLocalHost() throws UnknownHostException
▪ Returns the (main) IP address of the local computer
 If you have multiple interfaces: NetworkInterface.getNetworkInterfaces()

On top of IP, multiple protocols can be used
 UDP (User Datagram Protocol)
▪ Also unreliable; system sends a packet and forgets about it
▪ DatagramSocket, DatagramPacket, MulticastSocket
 TCP (Transmission Control Protocol)
▪ Reliable; resends unacknowledged data packets.
▪ Negotiates a connection; keeps it open until one side closes it
▪ Socket, ServerSocket
 …

Many protocols implemented on top of TCP/UDP
 HTTP, FTP, NNTP, SMTP, POP, IMAP, finger, gopher, …
▪ Java supports some of them
▪ URL, URLConnection, URLEncoder, …
4
jonkv@ida
Introduction 3: TCP and UDP
Multiple connections between two computers
 Uses "ports" (16-bit numbers) to identify connections
 Connection identified by:
<protocol, source IP, source port, dest IP, dest port>
Host B
65535
Port 65535
Port 1
Port 2
Port 3
1
2
3
Port 1
Port 2
Port 3
Port 65535
Host C
▪ Multiple connections to the same dest port (different sources!)
▪ For example, multiple connections to a web server on port 80
Host A

5
jonkv@ida
Introduction 4: TCP, UDP and Port Numbers
Reliable Communication:
TCP
Sockets and the Client/Server Model
jonas.kvarnstrom@liu.se – 2015

7
TCP networking is client/server-based
 A server continuously listens to a specific port
▪ HTTP servers usually listen to port 80
▪ NNTP servers usually listen to port 119
 Occasionally, clients connect to that port
▪ Web browsers try to connect to port 80
▪ News readers try to connect to port 119
 A
▪
▪
▪
successful connection results in a socket pair
A two-way pipeline for binary data
Anything written to socket A can be read from socket B
Anything written to socket B can be read from socket A
Socket/21754
Socket/80
jonkv@ida
TCP Networking using Sockets

8
First, the server sets up a ServerSocket
 The ServerSocket listens to a specific port
▪ ServerSocket ssock = new ServerSocket(80);
 Ready for clients to connect
▪ "Incoming calls" are placed in a queue
Listening for new connections on port 80…
ServerSocket/80
jonkv@ida
Sockets 1: Waiting for connections

9
The server calls accept()
 Picks a waiting client from the queue, or waits for one
▪ ServerSocket ssock = new ServerSocket(80);
Socket s = ssock.accept();
// Waiting…

Eventually a client creates a new Socket:
▪ Socket s = new Socket("server.com", 80);
Attempting to talk to server:80…
Socket/21754
// Maybe #21754
Connected to client:21754
ServerSocket/80
jonkv@ida
Sockets 2: Accepting a connection

10
The client socket connects to server.com:80
 … which was waiting in accept(),
so now it accepts the connection, and returns a new java.net.Socket
▪ Socket s = ssock.accept();
// Now accept() returns!
▪ Use this Socket to communicate with the client!
Once more listening for new connections on port 80…
ServerSocket/80
Connected to server.com:80
Socket/21754
Socket/80
jonkv@ida
Sockets 3: The Connection
Socket s = new Socket("server.com",80);
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
11
Uses InputStream
and OutputStream,
just like files!
ServerSocket ssock = new ServerSocket(80);
Socket s = ssock.accept();
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
Socket/21754
Socket/80
jonkv@ida
Sockets 4: Overview
Network Protocols
A complete client/server example
jonas.kvarnstrom@liu.se – 2015

13
What remains: A protocol
 Must exist – but can be very simple
 Example: RFC 862
▪ "A very useful debugging and measurement tool is an echo service. An echo service
simply sends back to the originating source any data it receives.
▪ TCP Based Echo Service:
One echo service is defined as a connection based application on TCP. A server
listens for TCP connections on TCP port 7. Once a connection is established any
data received is sent back. This continues until the calling user terminates the
connection.
▪ UDP Based Echo Service:
Another echo service is defined as a datagram based application on UDP. A server
listens for UDP datagrams on UDP port 7. When a datagram is received, the data
from it is sent back in an answering datagram."
jonkv@ida
Networking Protocols 1

To define your own protocol:
 Determine which kind of protocol
▪ Text-based
(Java: Reader / Writer)
▪ Binary
(Java: InputStream / OutputStream)
▪ Serialization-based (easy to send object structures but must use Java)
 Write a specification
 Implement the specification
 Find bugs and problems – update the specification and iterate
14
jonkv@ida
Networking Protocols 2

A simple server example
 Variation on the TCP/UDP echo service
▪ Accept a string, send it back
 First version:
▪ The string will consist of a single line
▪ Text will always be sent in ISO Latin-1
 Second version:
▪ Use serialization; no restrictions on the string
15
jonkv@ida
Servers 1: What do we want?
16
public class Server { // Runs on machine server.com
public final static String CS = "ISO-8859-1";
public static void main(final String[] args) {
try (ServerSocket serverSock = new ServerSocket(8189)) {
while (true) {
try (Socket sock = serverSock.accept();
InputStream in = sock.getInputStream();
Input Reader re = new InputStreamReader(in, CS);
BufferedReader br = new BufferedReader(re);
OutputStream out = sock.getOutputStream();
Output Writer wr = new OutputStreamWriter(out, CS);
PrintWriter pw = new PrintWriter(wr))
{
final String req = br.readLine();
// Read the request ...
pw.println(req);
// ... send the reply.
} catch (…) { … }
}
InputStreamReader
???InputStream
} BufferedReader
}
PrintWriter
OutputStreamWriter
???OutputStream
}
Socket
jonkv@ida
Servers 2: The Server Class
17
public class Client {
public final static String CS = "ISO-8859-1";
public static void main(final String[] args) {
try (Socket sock = new Socket("server.com", 8189);
InputStream in = sock.getInputStream();
Input
Reader re = new InputStreamReader(in, CS);
BufferedReader br = new BufferedReader(re);
OutputStream out = sock.getOutputStream();
Output
Writer wr = new OutputStreamWriter(out, CS);
PrintWriter pw = new PrintWriter(wr)
){
pw.println("Gazonk");
// Send the request…
pw.flush();
// Ensure it is sent…
System.out.println(br.readLine());
// … and read the reply
} catch (…) { … }
}
}
Closing the socket flushes
everything, so flush() was
not needed in the server.
jonkv@ida
Servers 3: The Client Class
public class SerializingServer {
public final static String CS = "ISO-8859-1";
public static void main(final String[] args) {
try (ServerSocket serverSock = new ServerSocket(8189)) {
while (true) {
try (Socket sock = serverSock.accept();
OutputStream out = sock.getOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(out);
InputStream in = sock.getInputStream();
ObjectInputStream oin = new ObjectInputStream(in))
{
final Object obj = oin.readObject();
// Read request…
if (!(obj instanceof String)) { /* Handle error, return */ }
oout.writeObject("OK");
// … send the reply.
} catch (…) { … }
}
} catch (…) { … }
}
}
18
jonkv@ida
Servers 4: Server with Serialization
19
public class SerializingClient {
public static void main(final String[] args) {
Object reply = null;
try (Socket sock = new Socket("server.com", 8189);
InputStream in = sock.getInputStream();
ObjectInputStream oin = new ObjectInputStream(in);
OutputStream out = sock.getOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(out)) {
oout.writeObject("Gazonk");
// Send the request…
oout.flush();
// Ensure it is sent, not buffered…
reply = oin.readObject();
// Read the reply
} catch (…) { … }
// Now the resources are closed – go on and process the reply
if (reply instanceof String) { Can easily send strings with special characters or newlines, or
String str = (String) reply;
lists of strings, or create your own Request/Reply classes…
System.out.println(str);
But can only communicate with other Java programs!
} else {
// Unexpected reply; handle error without crashing
}
jonkv@ida
Servers 5: Client with Serialization
 Note that:
▪ The client opened its ObjectInputStream first, but…
▪ … the server opened its ObjectOutputStream first.
 Why?
▪ The ObjectInputStream constructor reads a serialization header.
▪ Suppose both sides first opened an ObjectInputStream.
▪ Then, both would wait for a header from the other side.
▪ The ObjectOutputStream constructor writes a serialization header.
▪ Suppose both sides first opened an ObjectOutputStream.
▪ Then, both would write a serialization header.
▪ This should not be a problem, unless the header is very large
or the buffers are very small.
20
jonkv@ida
Servers 6: Using serialization
Multi-Threaded Servers
jonas.kvarnstrom@liu.se – 2015

22
The main loop in the simple server example:
 A client connects…
 … the server processes the entire request…
▪ Possibly spends a lot of time just waiting for I/O
 … and then, the server can accept a new client.
Client A calls…
Immediately setting up a connection
Client B calls…
but has to wait
Slowly receiving a long string
through a slow connection
B is handled
Reversing, sending the reply
jonkv@ida
Problems?

23
Solution: Write a multi-threaded server
 Accept a connection
 Handle it in another thread
 Main thread can quickly accept a new connection
Client B calls
Faster connection
and/or shorter string
Reply
Setting up connection A
and starting a new thread
Slowly receiving a long string
through a slow connection
Reversing, sending the reply
 (Alternative solution: Single thread + state machine)
jonkv@ida
Solution!
 ConnectionHandler does most of what Server used to do
class ConnectionHandler implements Runnable {
private final Socket sock;
public ConnectionHandler(final Socket sock) { this.sock = sock; }
public void run() {
try (InputStream in = sock.getInputStream();
Reader re = new InputStreamReader(in, ThreadedServer.CS);
BufferedReader br = new BufferedReader(re);
OutputStream out = sock.getOutputStream();
Writer wr = new OutputStreamWriter(out, ThreadedServer.CS);
PrintWriter pw = new PrintWriter(wr)) {
}
}
final String req = br.readLine();
// Read the request…
pw.println(req);
// … send the reply.
} catch (IOException ex) { /* handle this */ }
24
jonkv@ida
Threaded Servers 1: Connection Handler
 ThreadedServer is a skeleton that creates ConnectionHandlers
public class ThreadedServer {
public final static String CS = "ISO-8859-1";
public static void main(final String[] args) {
try (ServerSocket serverSock = new ServerSocket(8189)) {
while (true) {
try (Socket sock = serverSock.accept()) {
Runnable task = new ConnectionHandler(sock);
Thread thr = new Thread(task);
thr.start();
}
}
} catch (…) { … }
}
}
25
jonkv@ida
Threaded Servers 2: The Server

Still some problems…
 Unless we limit the number of threads,
▪ Anyone can create a huge number of connections…
▪ … which causes us to spawn a huge number of threads…
▪ … which may lead to OutOfMemoryException and other problems.
 Solution 1: Use a Semaphore
▪ Blocks when you try to allocate more than n "units"
 Solution 2: Use a standard thread pool
▪ For example, a ThreadPoolExecutor
26
jonkv@ida
Threaded Servers 3: Remaining Problems
Identifying and Locating
Resources
URIs and URLs
Accessing Network Resources through URLs
jonas.kvarnstrom@liu.se – 2015

URLs are represented by class java.net.URL
 Create:
▪ URL u1 = new URL("http://www.ida.liu.se/labs")
▪ URL u2 = new URL("http", "www.ida.liu.se", 80, "labs")
▪ URL u3 = new URL(u1, "kplab/teaching")
 Useful methods:
▪ getUserInfo(), getProtocol(), getHost(), getPort(), getPath(),
getRef(), getQuery()
▪ getContent()
▪ openStream()
▪ openConnection()
28
jonkv@ida
URLs 1: The URL Class

public InputStream openStream()
 Retrieves the raw content of the URL
▪ There must be a handler for the protocol
▪ Sun provides handlers for the most common protocols:
file, ftp, http, gopher, jar (and some more)
▪ You can provide your own handlers using a URLStreamHandlerFactory
 Read the InputStream like any other InputStream
▪ public static void main(String[] args) {
final URL url = new URL("http://myserver.com/mypic.gif");
final InputStream is = url.openStream();
final DataInputStream dis = new DataInputStream(is);
…
}
29
jonkv@ida
URLs 2: URL.openStream()

public Object getContent()
 Retrieves the raw content of the URL
▪ There must be a handler for the protocol (http, ftp, …)
 Parses the content, and returns an object
▪ An ImageProducer, a String, … — anything that has a content handler
▪ Sun provides handlers for:
image/jpeg, image/png, image/gif,
image/x-xbitmap, image/x-xpixmap
audio/aiff, audio/wav
text/plain
▪ Provide your own handlers using a ContentHandlerFactory
▪ public static void main(String[] args) {
final URL url = new URL("http://myserver/mypic.gif");
final ImageProducer ip = (ImageProducer) url.getContent();
…
}
30
jonkv@ida
URLs 3: URL.getContent()
References
jonas.kvarnstrom@liu.se – 2015

The Java Tutorial
 http://docs.oracle.com/java
se/tutorial/networking/

Optional Packages:
JavaMail
 Mail and news
▪ Sending, retrieving,
and storing messages
▪ Support for POP3, IMAP,
…
 http://www.oracle.com/tec
hnetwork/java/javamail/ind
ex.html
32
jonkv@ida
See Also
Download