Java Sockets and Server Sockets

‡ ‡ ‡ ‡

How data is transmitted across the Internet Sockets Server Sockets UDP

Applet 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

000 bytes. and often smaller than this. ‡ Datagrams range in size from a few dozen bytes to about 60. it is split into packets of varying but finite size called datagrams.Datagrams ‡ Before data is sent across the Internet from one host to another using TCP/IP. must be split into smaller pieces before they can be transmitted. ‡ Packets larger than this. .

‡ If packets arrive out of order they can be reordered at the receiving end of the connection. . it can be retransmitted without requiring redelivery of all other packets.Packets Allow Error Correction ‡ If one packet is lost.

‡ The host's native networking software transparently splits data into packets on the sending end of a connection. ‡ Instead. and then reassembles packets on the receiving end. the Java programmer is presented with a higher level abstraction called a socket.Abstraction ‡ Datagrams are mostly hidden from the Java programmer. .

and packets that arrive out of order. lost and retransmitted packets. ‡ There are limits.Sockets ‡ A socket is a reliable connection for the transmission of data between two hosts. ‡ Sockets isolate programmers from the details of packet encodings. Sockets are more likely to throw IOExceptions than files. .

‡ A socket may not reconnect after it's closed. These are: 1. Close the connection ‡ A socket may not be connected to more than one host at a time.Socket Operations ‡ There are four fundamental operations a socket performs. Receive data 4. Send data 3. Connect to a remote machine 2. .

‡ You can connect to remote machines. you can send data. you must create a new Socket object. you can receive data. ‡ Each Socket object is associated with exactly one remote host.Socket class ‡ The java. you can close the connection. To connect to a different host.The java.net.net. .Socket class allows you to create socket objects that perform all four fundamental socket operations.

IOException ‡ public Socket(InetAddress address. int port) throws UnknownHostException. ‡ public Socket(String host. int port. int port.Constructing a Socket ‡ Connection is accomplished through the constructors. int localPort) throws IOException ‡ public Socket(InetAddress address. InetAddress localAddr. int port) throws IOException ‡ public Socket(String host. InetAddress localAddr. int localPort) throws IOException .

‡ All the constructors throw an IOException if the connection can't be made for any reason.Opening Sockets ‡ The Socket() constructors do not just create a Socket object. . They also attempt to connect the underlying socket to the remote server.

‡ The host may be specified as either a string like "utopia.edu". ‡ The port should be an int between 1 and 65535.edu" or as an InetAddress object.‡ You must at least specify the remote host and port to connect to. ‡ Socket webMetalab = new Socket("metalab.poly.unc. . 80).

‡ You can use the constructors to determine which ports on a host are listening for connections.‡ You cannot just connect to any port on any host. . The remote host must actually be listening for connections on that port.

net. ± import java. ± class scantest ± { ± ± public static void main(String[] args) { ± String host = "localhost".*. ± } ± try { ± InetAddress theAddress= InetAddress.i++) ± { ± .length>0) ± { ± host=args[0].*. ± if(args.getByName(host). ± for(int i=1024.i<65536.io.± import java.

} catch (IOException ex) { // The remote host is not listening on this port } } catch(UnknownHostException ex) { System.println(ex).err.i). System. } } } .try { Socket thesocket =new Socket(theAddress.out.println("A server is listening on port "+i + " of " + host).

this allows you to pick your network interface and IP address. like many web servers.Picking an IP address ‡ The last two constructors also specify the host and port you're connecting from. . ‡ On a system with multiple IP addresses.

‡ Setting the port to 0 tells the system to randomly choose an available port.unc.oit. "calzone. ‡ If you need to know the port you're connecting from. Socket webMetalab = new Socket("metalab.edu". 0).Choosing a Local Port ‡ You can also specify a local port number.edu".unc. . you can always get it with getLocalPort(). 80.

‡ 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 .Sending and Receiving Data ‡ Data is sent and received with output and input streams.

Reading Input from a Socket ‡ The getInputStream() method returns an InputStream which reads data from the socket. ‡ Most of the time you'll chain the input stream to some other input stream or reader object to more easily handle the data. ‡ You can use all the normal methods of the InputStream class to read this data. .

and displays the data it sends. .out.unc. InputStreamReader isr = new InputStreamReader(in). 13). InputStream in = s. } catch (IOException e) { return (new Date()).readLine().edu". BufferedReader br = new BufferedReader(isr).getInputStream().For example ‡ The following code fragment connects to the daytime server on port 13 of metalab.toString().println(theTime). System. String theTime = br.unc.edu. try { Socket s = new Socket("metalab.

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

if (n > b. while (true) { int n = theInput. 9).getOutputStream().byte[] b = new byte[128].edu". } catch (IOException e) {} .length) n = b. 0.available(). OutputStream theOutput = s. 0. int m = theInput. } s. if (m == -1) break. theOutput. n). try { Socket s = new Socket("metalab.write(b.unc.read(b. n).length.close().

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

‡ Some protocols require the reads and the writes to be interlaced. That is:
± ± ± ± ± ± write read write read write read

‡ Other protocols, such as HTTP 1.0, have multiple writes, followed by multiple reads, like this:
± ± ± ± ± ± ± write write write read read read read

. ‡ 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.‡ Other protocols don't care and allow client requests and server responses to be freely intermixed.

getProtocol().getOutputStream(). if (u. OutputStream theOutput = s."). u. PrintWriter pw = new PrintWriter(theOutput. text/html.getInputStream(). String theLine.0\r\n").flush(). false).try { URL u = new URL(args[i]). pw.out. while ((theLine = br. InputStreamReader isr = new InputStreamReader(in).getFile() + " HTTP/1. } Socket s = new Socket(u.equalsIgnoreCase("http"))) { System. pw. BufferedReader br = new BufferedReader(isr).getPort() != -1) port = u. if (!(u. pw.print("\r\n").getPort()).println(theLine).print("GET " + u. text/*\r\n").getHost().readLine()) != null) { System. pw. InputStream in = s. } } catch (MalformedURLException e) { .println("I only understand http.err.print("Accept: text/plain.getPort().

Most of the time the defaults are fine.Socket Options ‡ Several methods set various socket options. 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 .

‡ These methods to return information about the socket: public public public public InetAddress getInetAddress() InetAddress getLocalAddress() int getPort() int getLocalPort() ‡ Finally there's the usual toString() method: public String toString() .

that is the host that initiates the connection.Servers ‡ There are two ends to each connection: the client. a program waits for other hosts to connect to it. that is the host that responds to the connection. ‡ Clients and servers are connected by sockets. rather than connecting to a remote host. and the server. ‡ A serve. .

.Server Sockets ‡ A server socket binds to a particular port on the local machine. it accepts the connection. ‡ Once it has successfully bound to a port. it listens for incoming connection attempts. This creates a socket between the client and the server over which the client and the server communicate. ‡ When a server detects a connection attempt.

‡ 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. ‡ 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.Multiple Clients ‡ Multiple clients can connect to the same port on the server at the same time.

server programs tend to be heavily multi-threaded. . ‡ Generally the server socket passes off the actual processing of connections to a separate thread.Threading ‡ 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.

‡ 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. .Queueing ‡ Incoming connections are stored in a queue until the server can accept them.

Socket object that performs the actual communication with the client. .ServerSocket class represents a server socket.ServerSocket Class ‡ The java. Then it calls accept() to listen for incoming connections. ‡ A ServerSocket object is constructed on a particular local port.The java.net.net. ‡ accept() blocks until a connection is detected. Then accept() returns a java.net.

and the IP address to bind to: public ServerSocket(int public ServerSocket(int IOException public ServerSocket(int InetAddress bindAddr) port) throws IOException port. int backlog. the queue length for incoming connections.Constructors ‡ There are three constructors that let you specify the port to bind to. throws IOException . int backlog) throws port.

} .println(e). } catch (IOException e) { System. like this: try { ServerSocket ss = new ServerSocket(80).Constructing Server Sockets ‡ Normally you only specify the port you want to listen on.err.

‡ For example.BindException. This includes non-Java processes or threads. it attempts to bind to the port on the local host given by the port argument. is thrown. then a java.net. ‡ No more than one process or thread can listen to a particular port at a time. if there's already an HTTP server running on port 80. a subclass of IOException.‡ When a ServerSocket object is created. ‡ If another server socket is already listening to the port. . you won't be able to bind to port 80.

‡ FTP . 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. ‡ 0 is a special port number. It tells Java to pick an available port.‡ 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. ‡ The getLocalPort() method tells you what port the server socket is listening on.

For example.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.err. ‡ ‡ ‡ ‡ ‡ ‡ try { ServerSocket httpd = new ServerSocket(80. } . } catch (IOException e) { System. 50).println(e).

int backlog. ‡ By default. ‡ You can modify that behavior with this constructor: ‡ ‡ public ServerSocket(int port.Choosing an IP address ‡ Many hosts have more than one IP address. InetAddress bindAddr)throws IOException . a server socket binds to all available IP addresses on a given port.

90"). ‡ } . ‡ } ‡ catch (IOException e) { ‡ System.Example ‡ try { ‡ InetAddress ia = InetAddress.1. 50.err.getByName("199.println(e). ia). ‡ ServerSocket ss = new ServerSocket(80.32.

‡ On a server with multiple IP addresses. public InetAddress getInetAddress() ‡ The getLocalPort() method tells you which port you're listening to. the getInetAddress() method tells you which one this server socket is listening to. public int getLocalPort() .

‡ public Socket accept() throws IOException ‡ public void close() throws IOException ‡ A server socket can¶t be reopened after it¶s closed .‡ The accept() and close() methods provide the basic functionality of a server socket.

‡ accept() returns a Socket object. . and its getInputStream() and getOutputStream() methods provide streams.Reading 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.

).err.getOutputStream()).Example ‡ ‡ ‡ ‡ ‡ ‡ ‡ ‡ ‡ ‡ ‡ ‡ try { ServerSocket ss = new ServerSocket(2345).println("Hello There!"). PrintWriter pw = new PrintWriter(s.println(e). } . } catch (IOException e) { System. s.accept().close().println("Goodbye now. Socket s = ss. pw. pw.

getOutputStream()). Socket s = ss.Better Example ‡ ‡ ‡ ‡ ‡ ‡ ‡ ‡ ‡ ‡ ‡ ‡ try { ServerSocket ss = new ServerSocket(2345). } catch (IOException e) { System. s. pw.accept().print("Hello There!\r\n").\r\n").print("Goodbye now.close().err. PrintWriter pw = new PrintWriter(s. } .println(e). pw.

print("Hello " + s.println(e).Writing Data to a Client try { ServerSocket ss = new ServerSocket(port).accept().getPort() + "\r\n").getOutputStream()).err.flush(). } catch (IOException e) {} } } catch (IOException e) { System. } .getInetAddress() + " on port " + s.getLocalPort() + "\r\n"). pw. pw.print("This is " + s. s.close().getLocalAddress() + " on port " + s. PrintWriter pw = new PrintWriter(s. while (true) { try { Socket s = ss. pw.

a server needs to both read a client request and write a response. .Interacting with a Client ‡ More commonly.

‡ 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. .Adding Threading to a Server ‡ It's better to make your server multithreaded.

Adding 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. ThreadedEchoServer tes = new ThreadedEchoServer(s) tes. ‡ } ‡ catch (IOException e) {} ‡ ‡ ‡ ‡ .start().accept().

a new thread gets created. especially on a heavily loaded server. 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.‡ Every time you pass through this loop. It would be better not to spawn so many threads.

store incoming connections in a queue. ‡ The main change you need to make to implement this is to call accept() in the run() method rather than in the main() method. and have the threads in the pool progressively remove connections from the queue and process them. .Thread Pools ‡ Create a pool of threads when the server launches.

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() throws IOException ‡ public static synchronized void setSocketFactory(SocketImplFactory fac) throws IOException .

Utility Methods ‡ Finally. there's the usual toString() method: ‡ ‡ public String toString() .

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 .UDP ‡ Unreliable Datagram Protocol ‡ Packet Oriented.

net.The UDP Classes ‡ Java's support for UDP is contained in two classes: java.net.DatagramSocket java. .DatagramPacket ‡ A datagram socket is used to send and receive datagram packets.

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

DatagramSocket ‡ A DatagramSocket object is a local connection to a port that does the sending and receiving.java. ‡ Also unlike TCP sockets. a DatagramSocket can send to multiple. ‡ There is no distinction between a UDP socket and a UDP server socket.net. not in the socket. . ‡ The address to which data goes is stored in the packet. different addresses.

‡ Each computer has 65.536 TCP ports.UDP ports ‡ Separate from TCP ports. .536 UDP ports as well as its 65. ‡ A server socket can be bound to TCP port 20 at the same time as a datagram socket is bound to UDP port 20.

second is for sending . int iport) ‡ First is for receiving. int length. InetAddress iaddr.Two DatagramPacket Constructors ‡ public DatagramPacket(byte[] data. int length) ‡ public DatagramPacket(byte[] data.

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

‡ DatagramPacket dp = new DatagramPacket(b. chargen). ‡ } .println(e). ‡ int chargen = 19.With a destination: ‡ try { ‡ InetAddress metalab = new InetAddess("metalab. b.length.err.unc.getBytes(). ‡ String s = "My second UDP Packet" ‡ byte[] b = s. metalab.edu"). ‡ } ‡ catch (UnknownHostException e) { ‡ System.

‡ public synchronized iaddr) ‡ public synchronized ‡ public synchronized ‡ public synchronized ‡ public synchronized ‡ public synchronized ‡ public synchronized ‡ public synchronized void setAddress(InetAddress void setPort(int iport) void setData(byte ibuf[]) void setLength(int ilength) InetAddress getAddress() int getPort() byte[] getData() int getLength() ‡ These methods are primarily useful when you're receiving datagrams. .DatagramPackets are not immutable.

‡ The second two are for server datagram sockets since they specify the port and optionally the IP address of the socket . InetAddress laddr) throws SocketException ‡ The first is for client datagram sockets. that is sockets that send datagrams before receiving any.java.DatagramSocket ‡ public DatagramSocket() throws SocketException ‡ public DatagramSocket(int port) throws SocketException ‡ public DatagramSocket(int port.net.

Sending UDP Datagrams ‡ To send data to a particular server ± Convert the data into byte array. ± Pass this byte array. ± Next create a DatagramSocket and pass the packet to its send() method . 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.

b.getBytes().send(dp).edu"). ‡ String s = "My second UDP Packet". ‡ int chargen = 19. . ‡ sender. chargen).For example. ‡ DatagramPacket dp = new DatagramPacket(b. ‡ DatagramSocket sender = new DatagramSocket().length. ‡ InetAddress metalab = new InetAddess("metalab.unc. ia. ‡ byte[] b = s.

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

‡ If the received packet was too long for the buffer. getData() to retrieve the data. . and getLength() to see how many bytes were in the data. ‡ Use getPort() and and getAddress() to tell where the packet came from.‡ dp is filled with the data from that datagram. it's truncated to the length of the buffer.

getPort() + " on " + incoming.getData().receive(incoming).out. ‡ ds. ‡ byte[] data = incoming.println(s). ‡ try { ‡ byte buffer = new byte[65536]. ‡ System. ‡ } . ‡ DatagramSocket ds = new DatagramSocket(2134).out. ‡ DatagramPacket incoming = new DatagramPacket(buffer. ‡ String s = new String(data.For example.getAddress() + " sent this message:"). data.getLength()). 0.length).println("Port " + incoming. buffer. ‡ System.

1999 ± ISBN 1-56592-485-1 .To Learn More ‡ Java Network Programming ± O¶Reilly & Associates. 1997 ± ISBN 1-56592-227-1 ‡ Java I/O ± O¶Reilly & Associates.

Questions? .

Sign up to vote on this title
UsefulNot useful