Java Socket Programming


Java Socket Programming

Elliotte Rusty Harold

Software Development 2003 West

March, 2003

elharo@metalab.unc.edu

http://www.cafeaulait.org/


We will learn how Java handles


I assume you


Applet Network Security Restrictions


Some Background


Hosts


Internet addresses


Domain Name System (DNS)


The InetAddress Class


Creating InetAddresses


The getByName() factory method


Other ways to create InetAddress objects


Getter Methods


Utility Methods


Ports


Protocols


Datagrams


Packets Allow Error Correction


Abstraction


Sockets


Socket Operations


The java.net.Socket class


Constructing a Socket


Opening Sockets


Choosing the Host and the Port


PortScanner

public static void scan(InetAddress remote) {

  String hostname = remote.getHostName();
  for (int port = 1; port < 65536; port++) {
    try {
      Socket s = new Socket(remote, port); 
      System.out.println("A server is listening on port "
       + port + " of " + hostname);
      s.close();
    }
    catch (IOException ex) {
      // The remote host is not listening on this port
    }
  }

}

Picking an IP address


Choosing a Local Port


Sending and Receiving Data


Reading Input from a Socket


Time Client

try {
  Socket s = new Socket("tock.usno.navy.mil", 13);
  InputStream in = s.getInputStream();
  InputStreamReader isr = new InputStreamReader(in);
  BufferedReader br = new BufferedReader(isr, "ASCII");
  int c;
  while ((c = br.read()) != -1) {
    System.out.print((char) c);
  }
  System.out.println();
}
catch (IOException ex) {
  return (new Date()).toString();
}

Writing Output to a Socket


Discard

byte[] b = new byte[128];

try {
  Socket s = new Socket("metalab.unc.edu", 9);
  OutputStream theOutput = s.getOutputStream();
  while (true) {
    int n = theInput.available();
    if (n > 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 ex) {}

Reading and Writing to a Socket


Synchronous


Request-Response

write
write
write
read
read
read
read

Asynchronous


Very Basic HTTP Client

import java.net.*;
import java.io.*;

public class SocketCat {

  public static void main(String[] args) {

    for (int i = 0; i < args.length; i++) {  
      int port = 80;
      String file = "/";
      try {
        URL u = new URL(args[i]);
        if (u.getPort() != -1) port = u.getPort();
        if (!(u.getProtocol().equalsIgnoreCase("http"))) {
          System.err.println("I only understand http.");
          continue;
        }
        if (!(u.getFile().equals(""))) file = u.getFile();
        Socket s = new Socket(u.getHost(), port);
        OutputStream theOutput = s.getOutputStream();
        PrintWriter pw = new PrintWriter(theOutput, false);
        pw.println("GET " + file + " HTTP/1.0");
        pw.println("Accept: text/plain, text/html, text/*");
        pw.println();
        pw.flush();
        
        InputStream in = s.getInputStream();
        InputStreamReader isr = new InputStreamReader(in);
        BufferedReader br = new BufferedReader(isr, "ASCII");
        String theLine;
        while ((theLine = br.readLine()) != null) {
          System.out.println(theLine);
        }
      }
      catch (MalformedURLException e) {
        System.err.println(args[i] + " is not a valid URL");
      }
      catch (IOException ex) {
        System.err.println(ex);
      }
      
    }
  
  }

}

Better Example

import java.net.*;
import java.io.*;

public class BetterCat {

  public static void main(String[] args) {

    for (int i = 0; i < args.length; i++) {  
      int port = 80;
      String file = "/";
      try {
        URL u = new URL(args[i]);
        if (u.getPort() != -1) port = u.getPort();
        if (!(u.getProtocol().equalsIgnoreCase("http"))) {
          System.err.println("I only understand http.");
        }
        if (!(u.getFile().equals(""))) file = u.getFile();
        Socket s = new Socket(u.getHost(), port);
        OutputStream theOutput = s.getOutputStream();
        OutputStreamWriter out = new OutputStreamWriter(theOutput);
        out.write("GET " + file + " HTTP/1.0\r\n");
        out.write("Accept: text/plain, text/html, text/*\r\n");
        out.write("\r\n");
        out.flush();
        theOutput.flush();
        
        InputStream in = s.getInputStream();
        InputStreamReader isr = new InputStreamReader(in);
        BufferedReader br = new BufferedReader(isr);
        int c;
        while ((c = br.read()) != -1) {
          System.out.print((char) c);
        }
      }
      catch (MalformedURLException ex) {
        System.err.println(args[i] + " is not a valid URL");
      }
      catch (IOException ex) {
        System.err.println(ex);
      }
      
    }
  
  }

}

Socket Options


Getter Methods


Servers


Server Sockets


Multiple Clients


Queueing


The java.net.ServerSocket Class


Constructors


Constructing Server Sockets


Binding to Ports


Port Numbers


Expanding the Queue


Choosing an IP address


Example

try {
 InetAddress ia = InetAddress.getByName("199.1.32.90");
 ServerSocket ss = new ServerSocket(80, 50, ia);
}
catch (IOException ex) {
 System.err.println(ex);
}

Checking the Port Number


Accepting Connection


Reading Data with a ServerSocket


A Simple Server

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 ex) {
  System.err.println(ex);
}

A Better Server

try {
 ServerSocket ss = new ServerSocket(2345);
 Socket s = ss.accept();
 Writer out = new BufferedWriter(
               new OutputStreamWriter(s.getOutputStream(), "UTF-8")
              );
 out.write("Hello There!\r\n");
 out.write("Goodbye now.\r\n");
 out.flush();
 s.close();
}
catch (IOException ex) {
 System.err.println(ex);
}

Writing Data to a Client


try {
  ServerSocket ss = new ServerSocket(port);
  while (true) {
    try {
      Socket s = ss.accept();
      Writer out = new OutputStreamWriter(s.getOutputStream());
      out = new BufferedWriter(out);
      out.write("Hello " + s.getInetAddress() + " on port " 
       + s.getPort() + "\r\n");
      out.write("This is " + s.getLocalAddress() + " on port " 
       + s.getLocalPort() + "\r\n");
      out.flush();
      s.close();
    }
    catch (IOException ex) {
      // skip this connection; continue with the next
    }
  }
}
catch (IOException ex) { 
  System.err.println(ex); 
}

Interacting with a Client


Threading


Adding Threading to a Server


Adding a Thread Pool to a Server


Thread Issues


Thread Pools


New I/O API


Setting Server Socket Options


Utility Methods


UDP


The UDP Classes


java.net.DatagramPacket


java.net.DatagramSocket


UDP ports


Two DatagramPacket Constructors


For example,

String s = "My first UDP Packet"
byte[] b = s.getBytes();
DatagramPacket dp = new DatagramPacket(b, b.length);

With a destination:

try {
  InetAddress metalab = new InetAddess("metalab.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(ex);
}

DatagramPackets are not immutable.

public synchronized void setAddress(InetAddress iaddr)
public synchronized void setPort(int iport) 
public synchronized void setData(byte ibuf[])
public synchronized void setLength(int ilength)
public synchronized InetAddress getAddress()
public synchronized int    getPort()
public synchronized byte[] getData()
public synchronized int    getLength()

java.net.DatagramSocket

public DatagramSocket() throws SocketException
public DatagramSocket(int port) throws SocketException
public DatagramSocket(int port, InetAddress laddr) throws SocketException

Sending UDP Datagrams


For example,

InetAddress metalab = new InetAddess("metalab.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);

Receiving UDP Datagrams


For example,

try {
  byte buffer = new byte[65536]; 
  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 ex) {
  System.err.println(ex);
}

Questions?


To Learn More



Index | Cafe con Leche

Copyright 2003 Elliotte Rusty Harold
elharo@metalab.unc.edu
Last Modified February 13, 2003