advanced socket programming in java - tripod.comlimat-cse.tripod.com/limatlecture-11.pdf · tcp...

40
Advanced Socket Programming in Java

Upload: phungphuc

Post on 09-Jul-2018

319 views

Category:

Documents


3 download

TRANSCRIPT

Advanced Socket Programming in Java

TCP/IP Protocol suite

•When you write java program that communicate over network you are working at Application Layer

•Typically you donot need to be concerned with TCP/UDP layers

•Instead the classes in java.net package provide system independent network communication

•But to understand which java classes a program is using you need to understand the difference between TCP and UDP.

TCP versus UDP• Transmission Control Protocol(TCP)

– Set up the Connection first, then Send Data– After Exchanging Data, Need the Procedure for

Releasing Connection – Similar to Telephone Communication– High Reliability – High overload to release the connection -> Not

efficient for small data• User Datagram Protocol(UDP)

– Without Connection, Split data into Packet with fixed length, Attach address, then transmit them.

– Similar to Mail – Low Reliability

TCP/UDP

TCPTCP

UDPUDP

TCP Server Socket

• java.net.ServerSocket class• Binds to a local port to listen for initial

connections• Can be bound to a local IP for multi-homed

machines• accept() method returns a java.net.Socket, not an integer descriptor

TCP Client Socket

• java.net.Socket class• Combines socket with socket options

(timeout, linger, keep alive, no delay, etc)• Encapsulates a java.io.InputStream and

a java.io.OutputStream – can be retrieved for use in a layered I/O system

UDP Socket

• java.net.DatagramSocket class• Java makes no distinction between

client/server for UDP sockets• Connected mode UDP supported in Java 2• Can be bound to both a local port & a local

IP address – multi-homed support• Supports some socket options (timeout,

buffer size)

UDP Datagram

• java.net.DatagramPacket class• Expects a byte array of data• Address optional for connected-mode UDP• This class is final – can’t be extended!• java.net.DatagramSocket instances

can only send instances of java.net.DatagramPacket

Socket Programming in java

• A socket is an endpoint of a two-way communication link between two programs running on the network.

• A socket is bound to a port number so that the TCP layer can identify the application that data destined to be sent.

• Java’s .net package provides two classes:– Socket – for implementing a client– ServerSocket – for implementing a server

Implementing a server socket1. Open the Server Socket:

ServerSocket server;DataOutputStream os;DataInputStream is;server = new ServerSocket( PORT );

2. Wait for the Client Request:Socket client = server.accept();

3. Create I/O streams for communicating to the clientis = new DataInputStream( client.getInputStream() );os = new DataOutputStream( client.getOutputStream() );

4. Perform communication with clientReceive from client: String line = is.readLine(); Send to client: os.writeBytes("Hello\n");

5. Close sockets: client.close();For multithreaded server:

while(true) {i. wait for client requests (step 2 above)

ii. create a thread with “client” socket as parameter (the thread creates streams (as in step (3) and does communication as stated in (4). Remove thread once service is provided.

}

Implementing a Client

1. Create a Socket Object:client = new Socket( server, port_id );

2. Create I/O streams for communicating with the server.is = new DataInputStream(client.getInputStream() );os = new DataOutputStream( client.getOutputStream() );

3. Perform I/O or communication with the server:– Receive data from the server:

String line = is.readLine(); – Send data to the server:

os.writeBytes("Hello\n");4. Close the socket when done:

client.close();

Socket Classes

• Provides interface to TCP, UDP sockets• Socket

– TCP client sockets

• ServerSocket– TCP server sockets

• DatagramSocket– UDP sockets (server or client)

Constructors

• Socket() − Creates an unconnected socket, with the system-default type of SocketImpl.

• Socket(InetAddress address, int port) − Creates a stream socket and connects it to the specified port number at the specified IP address.

• Socket(InetAddress address, int port, InetAddress localAddr, int localPort) − Creates a socket and connects it to the specified remote address on the specified remote port.

• Socket(SocketImpl impl) − Creates an unconnected Socket with a user-specified SocketImpl.

• Socket(String host, int port) − Creates a stream socket and connects it to the specified port number on the named host.

• Socket(String host, int port, InetAddress localAddr, int localPort) −Creates a socket and connects it to the specified remote host on the specified remote port.

Socket Methods

• getInputStream()• getOutputStream()• close()• getInetAddress()• getPort()• getLocalPort()

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.Socketobject that performs the actual communication with the client.

Constructors

• 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 IOExceptionpublic ServerSocket(int port, int backlog) throws IOException

public ServerSocket(int port, int backlog,InetAddress networkInterface) throwsIOException

ServerSocket Methods

• accept()• close()• getInetAddress()• getLocalPort()

Setting 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() throwsIOException

• public static synchronized voidsetSocketFactory(SocketImplFactory fac) throwsIOException

ServerSocket & Exceptions

• public ServerSocket(int port) throws IOException– Creates a server socket on a specified port. – A port of 0 creates a socket on any free port. You can use

getLocalPort() to identify the (assigned) port on which this socket is listening.

– The maximum queue length for incoming connection indications (a request to connect) is set to 50. If a connection indication arrives when the queue is full, the connection is refused.

• Throws:– IOException - if an I/O error occurs when opening the socket.– SecurityException - if a security manager exists and its

checkListen method doesn't allow the operation.

Constructing 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);

}

• 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.

• 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

A Simple Server

// SimpleServer.java: a simple server programimport java.net.*;import java.io.*;public class SimpleServer {public static void main(String args[]) throws IOException {// Register service on port 1234ServerSocket s = new ServerSocket(1234);Socket s1=s.accept(); // Wait and accept a connection// Get a communication stream associated with the socketOutputStream s1out = s1.getOutputStream();DataOutputStream dos = new DataOutputStream (s1out);// Send a string!dos.writeUTF("Hi there");// Close the connection, but not the server socketdos.close();s1out.close();s1.close();

}}

A Simple Client

// SimpleClient.java: a simple client programimport java.net.*;import java.io.*;public class SimpleClient {public static void main(String args[]) throws IOException {// Open your connection to a server, at port 1234Socket s1 = new Socket("mundroo.cs.mu.oz.au",1234);// Get an input file handle from the socket and read the inputInputStream s1In = s1.getInputStream();DataInputStream dis = new DataInputStream(s1In);String st = new String (dis.readUTF());System.out.println(st);// When done, just close the connection and exitdis.close();s1In.close();s1.close();

}}

Expanding 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);• }

Finding a free portimport java.io.*;import java.net.*;class findAPort {public static void main (String[] args) {for (int i = 1024; i < 65535; i++) {try {ServerSocket freePort = new ServerSocket(i);System.out.println("The first free port is: " + i);freePort.close(); // always a good practice to close when finishedSystem.exit(i); // to exit the loop and program; i is arbitrary} catch(IOException ioe) {// control falls into this block if there is a server on port i}} // end for} // end main} // end findAPort

Server in loop// SimpleServerLoop.java: a simple server program that runs forever in a single theadimport java.net.*;import java.io.*;public class SimpleServerLoop {public static void main(String args[]) throws IOException {// Register service on port 1234ServerSocket s = new ServerSocket(1234);while(true){

Socket s1=s.accept(); // Wait and accept a connection// Get a communication stream associated with the socketOutputStream s1out = s1.getOutputStream();DataOutputStream dos = new DataOutputStream (s1out);// Send a string!dos.writeUTF("Hi there");// Close the connection, but not the server socketdos.close();s1out.close();s1.close();

}}

}

To find a TCP port

import java.io.*;import java.net.*;class viewPorts {

public static void main (String[] args) {Socket socketIn;String host = "localhost";If (args.length > 0) {host = args[0];}for (int i = 0; i < 1024; i++) {

try {socketIn = new Socket(host, i); // to open a socketSystem.out.println("Port " + i + " hosts TCP service");socketIn.close(); // to close the open socket}catch(UnknownHostException uhe) {System.err.println(uhe);break;} catch(IOException ioe) {

// System.out.println("Port " + i + " does not host TCP service");// output statement is commented out to avoid a lengthy output}} // end for} // end main} // end viewPorts

Access SMTP from Socket

import java.io.*;import java.net.*;class smtp {public static void main (String[] args) {

String host = "localhost"; // default is local hostString mesg = "mail from: [email protected]" + "\n" +"rcpt to: [email protected]\n" + "data\n" + "This is a test\n"

+ ".\n" + "quit\n";if (args.length > 0){ host = args[0]; }

try {Socket socketIO = new Socket(host, 25); // 25 is smtp serverDataInputStream socketIn =new DataInputStream(socketIO.getInputStream());DataOutputStream socketOut =new DataOutputStream(socketIO.getOutputStream());socketOut.writeBytes(mesg); // write to socketwhile (true) {System.out.write(socketIn.readByte());} } // end trycatch(UnknownHostException uhe) { System.err.println(uhe); } catch(IOException ioe) { //System.out.println(ioe); } finally { System.out.println(); //socketIO.close(); //not defined here }} // end main} // end smtp

The UDP Classes

• Java's support for UDP is contained in two classes:java.net.DatagramSocketjava.net.DatagramPacket

• A datagram socket is used to send and receive datagram packets.

java.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.

java.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 DatagramSocketcan send to multiple, different addresses.

• The address to which data goes is stored in the packet, not in the socket.

UDP 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.

Datagram socket constructors

• DatagramSocket() − Constructs a datagram socket and binds it to any available port on the local host machine.

• DatagramSocket(int port) − Constructs a datagram socket and binds it to the specified port on the local host machine.

• DatagramSocket(int port, InetAddress laddr) −Creates a datagram socket, bound to the specified local address.

Datagram socket Methods

close()

getLocalAddress()

getLocalPort()

receive(DatagramPacket p)

send(DatagramPacket p)

setSoTimeout(int t)

getSoTimeout()

Datagram Packet class

This class represents a datagram packet.° The DatagramPacket class assembles data

bytes into packets called datagrams for delivery.

° It disassembles and extracts data contents from datagrams received from a remote site.

Two DatagramPacketConstructors

DatagramPacket(byte[] buf, int length) − Constructs aDatagramPacket for receiving packets of length length.

DatagramPacket(byte[] buf, int offset, int length) − Constructs a DatagramPacket for receiving packets of length length, specifying an offset into the buffer.

DatagramPacket(byte[] buf, int length, InetAddress address, intport) − Constructs a datagram packet for sending packets of length length to the specified port number on the specified host.

DatagramPacket(byte[] buf, int offset, int length, InetAddressaddress, int port) − Constructs a datagram packet for sending packets of length length with offset offset to the specified port number on the specified host.

Datagram packet methods

• getAddress()• getData()• getLength()• getPort()• setAddress()• setData()• setLength()• setPort()

Java server UDP exampleimport java.io.*; import java.net.*;

class UDPServer { public static void main(String args[]) throws Exception

{

DatagramSocket serverSocket =new DatagramSocket(9876);

byte[] receiveData = new byte[1024]; byte[] sendData = new byte[1024];

while(true) {

DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);

serverSocket.receive(receivePacket);

String sentence = new String(receivePacket.getData());

InetAddress IPAddress = receivePacket.getAddress();

int port = receivePacket.getPort();

String capitalizedSentence = sentence.toUpperCase();

sendData = capitalizedSentence.getBytes();

DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length,

IPAddress, port);

serverSocket.send(sendPacket); }

}

}

A UDP Client

import java.io.*;

import java.net.*;

class UDPClient {

public static void main(String args[]) throws Exception {

BufferedReader inFromUser =

new BufferedReader(new InputStreamReader(System.in));

DatagramSocket clientSocket = new DatagramSocket();

InetAddress IPAddress = InetAddress.getByName("hostname");

byte[] sendData = new byte[1024];

byte[] receiveData = new byte[1024];

String sentence = inFromUser.readLine();

sendData = sentence.getBytes();

DatagramPacket sendPacket =

new DatagramPacket(sendData, sendData.length,IPAddress, 9876);

clientSocket.send(sendPacket);

DatagramPacket receivePacket =

new DatagramPacket(receiveData, receiveData.length);

clientSocket.receive(receivePacket);

String modifiedSentence =

new String(receivePacket.getData());

System.out.println("FROM SERVER:" + modifiedSentence);

clientSocket.close();

} }