text: Preface
  For years, college courses in comput er networking were taught with little or no hands on expe-
  rience. For various reasons, including some good ones, instructors approached the principles
  of comput er networking primarily t hrough equations, analyses, and abstract descriptions of
  protocol stacks. Textbooks might have included code, but it would have been unconnect ed to
  anything st udent s could get their hands on. We believe, however, that st udent s learn better
  when they can see (and then build) concrete examples of the principles at work. And, for-
  tunately, things have changed. The Internet has become a part of everyday life, and access
  to its services is readily available to most st udent s (and their programs). Moreover, copious
  exampl esugood and bad- - of nontrivial software are freely available.
  We wrote this book for the same reason we wrote TCP/IP Sockets in C: we needed a
  resource to support learning networking t hrough programmi ng exercises in our courses. Our
  goal is to provide a sufficient introduction so that st udent s can get their hands on real network
  services without too much hand-holding. After grasping the basics, st udent s can then move on
  to more advanced assignments, which support learning about routing algorithms, multimedia
  protocols, medi um access control, and so on. We have tried to make this book equivalent to
  our earlier book to enable instructors to allow st udent s to choose the language they use and
  still ensure that all st udent s will come away with the same skills and understanding. Of course,
  it is not clear that this goal is achievable, but in any case the scope, price, and present at i on
  level of the book are intended to be similar.
  Intended Audience
  This book is aimed primarily at st udent s in upper-division undergraduat e or graduate courses
  in comput er networks. It is intended as a suppl ement to a traditional textbook that explains the
  problems and principles of comput er networks. At the same time, we have tried to make the
  ix
  X Preface m
  book reasonably self-contained (except for the assumed programmi ng background), so that it
  can also be used, for example, in courses on operating systems or distributed computing. For
  uses outside the context of a networking course, it will be helpful if the students have some
  acquaintance with the basic concepts of networking and TCP/IP.
  This book's other target audience consists of practitioners who know Java and want to
  learn about writing Java applications that use TCP/IP. This book should take such users far
  enough that they can start experimenting and learning on their own. Readers are assumed
  to have access to a comput er equipped with Java. This book is based on Version 1.3 of Java
  and the Java Virtual Machine (JVM); however, the code should work with earlier versions of
  Java, with the exception of a few new Java methods. Java is about portability, so the particular
  hardware and operating syst em (OS) on which you run should not matter.
  Approach
  Chapter 1 provides a general overview of networking concepts. It is not, by any means, a com-
  plete introduction, but rather is intended to allow readers to synchronize with the concepts and
  terminology used t hroughout the book. Chapter 2 introduces the mechanics of simple clients
  and servers; the code in this chapter can serve as a starting point for a variety of exercises.
  Chapter 3 covers the basics of message construction and parsing. The reader who digests the
  first three chapters should in principle be able to i mpl ement a client and server for a given
  (simple) application protocol. Chapter 4 then deals with techniques that are necessary when
  building more sophisticated and robust clients and servers. Finally, in keeping with our goal
  of illustrating principles through programming, Chapter 5 discusses the relationship between
  the programmi ng constructs and the underlying protocol i mpl ement at i ons in somewhat more
  detail.
  Our general approach introduces programmi ng concepts t hrough simple program exam-
  ples accompanied by line-by-line comment ary that describes the purpose of every part of the
  program. This lets you see the i mport ant objects and met hods as they are used in context. As
  you look at the code, you should be able to underst and the purpose of each and every line.
  Java makes many things easier, but it does not support some functionality that is
  commonl y associated with the C/UNIX sockets interface (asynchronous I/O, select( )-style
  multiplexing). In C and C++, the socket interface is a generic application programmi ng interface
  (API) for all types of protocols, not j ust TCP/IP. Java's socket classes, on the other hand, by
  default work exclusively with TCP and UDP over IPv4. Ironically, there does not seem to be
  anything in the Java specification or document at i on that requires that an instance of the Socket
  class use TCP, or that a DatagramSoeket instance use UDP. Nevertheless, this book assumes this
  to be the case, as is true of current implementations.
  Our examples do not take advantage of all library facilities in Java. Some of these facilities,
  in particular serialization, effectively require that all communicating peers be i mpl ement ed in
  Java. Also, to introduce examples as soon as possible, we wanted to avoid bringing in a thicket of
  met hods and classes that have to be sorted out later. We have tried to keep it simple, especially
  in the early chapters.
  What This Book Is Not xi
  What This Book Is Not
  To keep the price of this book within a reasonable range for a suppl ement ary text, we have
  had to limit its scope and mai nt ai n a tight focus on the goals outlined above. We omi t t ed many
  topics and directions, so it is probabl y wort h ment i oni ng some of the things this book is not:
  It is not an introduction to Java. We focus specifically on TCP/IP socket programmi ng
  using the Java language. We expect that the reader is already acquainted with the language
  and basic Java libraries (especially I/O), and knows how to develop programs in Java.
  It is not a book on protocols. Reading this book will not make you an expert on IP, TCP,
  FTP, HTTP, or any other existing prot ocol (except maybe the echo protocol). Our focus is
  on the interface to the TCP/IP services provi ded by the socket abstraction. (It will help if
  you start with some idea about tl~e general workings of TCP and IP, but Chapter 1 may
  be an adequate substitute.)
  It is not a guide to all of Java's rich collection of libraries that are designed to hide
  communi cat i on details (e.g., HTTPConnection) and make the pr ogr ammer's life easier.
  Since we are teaching the fundament al s of how to do, not how to avoid doing, prot ocol
  development, we do not cover these parts of the API. We want readers to underst and
  protocols in t erms of what goes on the wire, so we most l y use simple byt e st reams and
  deal with character encodings explicitly. As a consequence, this text does not deal with
  URL, URLConnection, and so on. We believe that once you underst and the principles, using
  these convenience classes will be straightforward. The network-relevant classes that we
  do cover include InetAddress, Socket, ServerSocket, DatagramPacket, DatagramSoeket, and
  UulticastSocket.
  It is not a book on object-oriented design. Our focus is on the i mport ant principles of
  TCP/IP socket programmi ng, and our examples are i nt ended to illustrate t hem concisely.
  As far as possible, we try to adhere to object-oriented design principles; however, when
  doing so adds complexity that obfuscat es the socket principles or bl oat s the code, we
  sacrifice design for clarity. This text does not cover design pat t erns for networking.
  (Though we would like to think that it provides some of the background necessary for
  underst andi ng such patterns!)
  It is not a book on writing production-quality code. Again, t houghwe strive for robust ness,
  the pri mary goal of our code exampl es is education. In order to avoid obscuring the
  principles with large amount s of error-handling code, we have sacrificed some robust ness
  for brevity and clarity.
  It is not a book on doing your own native sockets i mpl ement at i on in Java. We focus
  exclusively on TCP/IP sockets as provi ded by the st andard Java distribution and do not
  cover the various socket i mpl ement at i on wrapper classes (e.g., Socketlmpl).
  To avoid cluttering the exampl es with extraneous (nonsocket-related programmi ng) code,
  we have made t hem command-l i ne based. While the book's Web site,
  practical/javasockets, contains a few exampl es of GUI-enhanced net work applications,
  we do not include or explain t hem in this text.
  Xl l Preface u
  It is not a book on Java applets. Applets use the same Java networking API so the commu-
  nication code should be very similar; however, there are severe security restrictions on
  the kinds of communi cat i on an appl et can perform. We provide a very limited discussion
  of these restrictions and a single appl et/appl i cat i on exampl e on the Web site; however,
  a compl et e description of applet networking is beyond the scope of this text.
  This book will not make you an expert --t hat takes years of experience. However, we hope
  it will be useful as a resource, even to those who already know quite a bit about using sockets
  in Java. Both of us enjoyed writing it and learned quite a bit along the way.
  Acknowledgments
  We would like to t hank all the peopl e who helped make this book a reality. Despite the book's
  brevity, many hours went into reviewing the original proposal and the draft, and the reviewers'
  input has significantly shaped the final result.
  First, t hanks to those who meticulously reviewed the draft of the text and made sugges-
  tions for i mprovement. These include Michel Barbeau, Carlton University; Chris Edmondson-
  Yurkanan, University of Texas at Austin, Ted Herman, University of Iowa; Dave Hollinger,
  Rensselaer Polytecnic Institute; Jim Leone, Rochester Institute of Technology; Dan Schmidt,
  Texas A&M University; Erick Wagner, EDS; and CSI4321, Spring 2001. Any errors that remai n
  are, of course, our responsibility. We are very interested in weeding out such errors in future
  printings so if you find one, please email either of us. We will mai nt ai n an errata list on the
  book's Web page.
  Finally, we are grateful to the folks at Morgan Kaufmarm. They care about quality and
  we appreciate that. We especially appreciate the efforts of Karyn Johnson, our editor, and Mei
  Levenson, our product i on coordinator.
  Feedback
  We invite your suggestions for the i mpr ovement of any aspect of this book. You can send
  feedback via the book's Web page,, or you can email us at
  the addresses below:
  Kenneth L. Calvert calvert@netlab.uky.edu
  Michael J. Donahoo Jeff_Donahoo@baylor.edu
  chapt er 1
  Introduction
  Mi l l i ons of comput er s all over the worl d are now connect ed to the worl dwi de net work
  known as the Internet. The Int ernet enables pr ogr ams runni ng on comput er s t housands of
  miles apart to communi cat e and exchange i nformat i on. If you have a comput er connect ed to a
  network, you may have used a Web br owser - - a typical pr ogr am t hat makes use of the Internet.
  What does such a pr ogr am do to communi cat e with ot hers over a net work? The answer varies
  with the appl i cat i on and the operat i ng syst em (OS), but a great many pr ogr ams get access to
  net work communi cat i on services t hr ough the sockets appl i cat i on pr ogr ammi ng interface (API).
  The goal of this book is to get you st art ed writing Java pr ogr ams that use the sockets API.
  Before delving into the details of the API, it is wor t h taking a brief look at the big picture
  of net works and prot ocol s to see how an API for Transmi ssi on Control Prot ocol/Int ernet
  Protocol fits in. Our goal here is not to t each you how net works and TCP/IP wor k- - many fine
  texts are available for t hat pur pose [2, 4, 11, 16, 22J--but rat her to i nt roduce some basic
  concept s and terminology.
  1.1 Networks, Packets, and Protocols
  A comput er net work consi st s of machi nes i nt erconnect ed by communi cat i on channels. We
  call these machi nes hosts and routers. Hosts are comput er s t hat r un appl i cat i ons such as your
  Web browser. The appl i cat i on pr ogr ams runni ng on host s are really the users of the network.
  Routers are machi nes whose job is to relay, or forward, i nformat i on f r om one communi cat i on
  channel to anot her. They may run pr ogr ams but typically do not run appl i cat i on programs. For
  our purposes, a communication channel is a means of conveying sequences of bytes from one
  host to another; it may be a broadcast t echnol ogy like Ethernet, a dial-up modem connection,
  or somet hi ng more sophi st i cat ed.
  Rout ers are i mpor t ant simply because it is not practical to connect every host directly
  to every ot her host. Instead, a few host s connect to a router, whi ch connect s to ot her routers,
  and so on to form the network. This ar r angement lets each machi ne get by with a relatively
  2 Chapter 1: Introduction []
  I,,L]
  A
  W
  Channel
  (e.g., Ethernet)
  " I
  1 ! ( IP ] ' ~ Channel "~
  I I I
  L
  d,p]
  Host Router Host
  Fi gure 1.1 : A TCP/IP network. figure out how to forward each packet.
  A protocol is an agreement about the packets exchanged by communicating programs
  and what they mean. A protocol tells how packets are structured--for example, where the
  destination information is located in the packet and how big it ismas well as how the infor-
  mation is to be interpreted. A protocol is usually designed to solve a specific
  protocols, applications, and the sockets API in the hosts and routers, as well as the flow
  of data from one application (using TCP) to another. The boxes labeled TCP, UDP, and IP
  represent implementations of those protocols. Such implementations typically reside in the
  [] 1.2 About Addresses
  operating system of a host. Applications access the services provided by UDP and TCP through
  the sockets API. The arrow depicts the flow of data from the application, t hrough the TCP and IP
  implementations, t hrough the network, and back up through the IP and TCP implementations
  at the other end.
  In TCP/IP, the bot t om layer consists of the underlying communication channel snfor-effort protocol: it attempts
  to deliver each packet, but it can (and occasionally does) lose, reorder, or duplicate packets in
  transit t hrough the network.
  The layer above IP is called the transport layer. It offers a choice between two protocols:
  TCP and UDP. Each builds on the service provided by IP, but they do so in different ways to
  provide different kinds of transport, which are used by application protocols with different
  needs. TCP and UDP have one function in common: addressing. Recall that IP delivers packets
  to hosts; clearly, a finer granularity of addressing is needed to get a packet to a particular
  application, perhaps one of many using the network on the same host. Both TCP and UDP
  use addresses, called port numbers, to identify applications within hosts. They
  channel, so that applications do not have to deal with these problems. It is a connection-
  oriented protocol: before using it to communicate, two programs must first establish a TCP
  connection, which involves completing an exchange of handshake messages between the TCP
  implementations on the two communicating computers. Using TCP is also similar in many ways
  to file i nput/out put (I/O). In fact, a file that is written by one program and read by another is a
  reasonable model of communication over a TCP connection. UDP, on the other hand, does
  not attempt to recover from errors experienced by IP; it simply extends the IP best-effort
  datagram their
  number to the telephone system. In a similar way, before a program can communicate with
  4 Chapter 1: Introduction I
  anot her program, it must tell the net work where to find the other program. In TCP/IP, it takes
  two pieces of i nformat i on to identify a particular program: an Internet address, used by IP, and
  a port number, the additional address i nt erpret ed by the t ransport protocol (TCP or UDP).
  Internet addresses are 32-bit binary numbers. 1 In writing down Internet addresses for
  human consumpt i on (as opposed to using t hem inside applications), we typically show t hem
  as a string of four decimal numbers separat ed by periods (e.g., 10.1.2.3); this is called the
  dotted-quad notation. The four numbers in a dot t ed-quad string represent the cont ent s of the
  four byt es of the Internet address--t hus, each is a number bet ween 0 and 255.
  One special IP address wort h knowing is the loopback address, 127.0.0.1. This address
  is always assi gned to a special loopback interface, which simply echoes t ransmi t t ed packet s
  right back to the sender. The l oopback interface is very useful for testing; it can be used even
  when a comput er is not connect ed to the network.
  Technically, each Internet address refers to the connection bet ween a host and an
  underl yi ng communi cat i on channel, such as a dial-up modem or Ethernet card. Because each
  such net work connect i on belongs to a single host, an Internet address identifies a host as
  well as its connect i on to the network. However, because a host can have multiple physical
  connect i ons to the network, one host can have multiple Internet addresses.
  The port number in TCP or UDP is always i nt erpret ed relative to an Internet address.
  Returning to our earlier analogies, a port number corresponds to a room number at a given
  street address, say, that of a large building. The postal service uses the street address to get the
  letter to a mailbox; whoever empt i es the mailbox is t hen responsible for getting the letter to the
  proper room within the building. Or consider a company with an internal telephone system:
  to speak to an individual in the company, you first dial the company's mai n phone number to
  connect to the internal telephone syst em and t hen dial the extension of the particular t el ephone
  of the individual t hat you wish to speak with. In these analogies, the Internet address is the
  street address or the company's mai n number, whereas the port corresponds to the r oom
  number or t el ephone extension. Port number s are 16-bit unsi gned binary numbers, so each
  one is in the range 1 to 65,535 (0 is reserved).
  1.3 About Names
  Most likely you are accust omed to referring to host s by name (e.g., host.example.com). How-
  ever, the Internet protocols deal with numeri cal addresses, not names. You shoul d under st and
  t hat the use of names i nst ead of addresses is a convenience feature that is i ndependent of
  the basic service provi ded by TCP/IP--you can write and use TCP/IP applications wi t hout ever
  1Throughout this book the term Internet address refers to the addresses used with the current version of
  IP, which is version 4 [12]. Because it is expected that a 32-bit address space will be inadequate for future
  needs, a new version of IP has been defined [5]; it provides the same service but has much bigger Internet
  addresses (128 bits). IPv6, as the new version is known, has not been widely deployed; the sockets API will
  require some changes to deal with its much larger addresses [6].
  [] 1.4 Clients and Servers
  usi ng a name. When you use a name to identify a communi cat i on endpoi nt, the syst em has to
  do some extra work to resolve the name into an address.
  This extra step is oft en wort h it, for a couple of reasons. First, names are generally
  easier for humans to r emember t han dot t ed-quads. Second, names provi de a level of indi-
  rection, whi ch i nsul at es users from IP address changes. During the writing of this book, the
  Web server for the publ i sher of this text, Morgan Kaufmann, changed Int ernet addresses
  from 208.164.121.48 to 216.200.143.124. However, because we refer to t hat Web server as (clearly much easier to r emember t han 208.164.121.48) and because the change
  is reflected in the syst em t hat maps names to addresses ( now resolves to the
  new Int ernet address i nst ead of 208.164.121.48), the change is t r anspar ent to pr ogr ams that
  use the name to access the Web server.
  The name-resol ut i on service can access i nformat i on f r om a wide variety of sources. Two
  of the pri mary sources are the Domain Name System (DNS) and local confi gurat i on dat abases.
  The DNS [9] is a di st ri but ed dat abase that maps domain names such as to
  Int ernet addresses and ot her i nformat i on; the DNS prot ocol [10] allows host s connect ed to
  the Int ernet to retrieve i nformat i on from that dat abase usi ng TCP or UDP. Local confi gurat i on
  dat abases are generally OS-specific mechani sms for local name-t o-Int ernet address mappi ngs.
  1.4 Clients and Servers
  In our post al and t el ephone analogies, each communi cat i on is initiated by one party, who sends
  a letter or makes the t el ephone call, while the ot her part y r esponds to the initiator's cont act by
  sendi ng a r et ur n letter or picking up the phone and talking. Int ernet communi cat i on is similar.
  The t erms client and server refer to t hese roles: The client pr ogr am initiates communi cat i on,
  while the server pr ogr am waits passively for and t hen r esponds to clients t hat cont act it.
  Together, the client and server compose the application. The t erms client and server are
  descriptive of the typical si t uat i on in whi ch the server makes a part i cul ar capabi l i t y--for
  example, a dat abase service--available to any client t hat is able to communi cat e with it.
  Whet her a pr ogr am is acting as a client or server det ermi nes the general form of its
  use of the sockets API to est abl i sh communi cat i on with its peer. (The client is the peer of the
  server and vice versa.) Beyond that, the client-server di st i nct i on is i mpor t ant because the client
  needs to know the server's address and port initially, but not vice versa. With the sockets API,
  the server can, if necessary, learn the client's address i nformat i on when it receives the initial
  communi cat i on from the client. This is anal ogous to a t el ephone call--in order to be called, a
  per son does not need to know the t el ephone number of the caller. As with a t el ephone call,
  once the connect i on is established, the di st i nct i on bet ween server and client di sappears.
  How does a client find out a server's IP address and port number? Usually, the client
  knows the name of the server it want smf or example, from a Universal Resource Locator (URL)
  such as uses the name-resol ut i on service to learn the correspondi ng
  Int ernet address.
  Finding a server's port number is a different story. In principle, servers can use any port,
  but the client must be able to learn what it is. In the Internet, t here is a convent i on of assigning
  well-known port number s to certain applications. The Int ernet Assi gned Number Aut hori t y
  6 Chapter 1: Introduction u
  (IANA) oversees this assignment. For example, port number 21 has been assigned to the File
  Transfer Protocol (FTP). When you run an FTP client application, it tries to contact the FTP
  server on that port by default. A list of all the assigned port numbers is maintained by the
  numbering authority of the Internet (see).
  1.5 What Is a Socket?
  A socket is an abstraction through which an application may send and receive data, in much
  the same way as an open file. Datagram
  sockets use UDP (again, with IP underneath) and thus provide a best-effort datagram service that
  applications can use to send individual messages up to about 65,500 bytes in length. Stream
  and datagram sockets are also support ed by other protocol suites, but this book deals only
  with TCP stream sockets and UDP datagram sockets. A TCP/IP socket is uniquely identified by
  an Internet address, an end-to-end protocol (TCP or UDP), and a port number. As you proceed,
  you will encounter several ways for a socket to become bound to an address.
  Figure 1.2 depicts the logical relationships among applications, socket abstractions,
  protocols, and port numbers within a single host. Note that a single socket abstraction can
  be referenced by multiple application programs. Each program that has a reference to a
  particular socket can communicate t hrough that socket. Earlier we said that a port identifies
  an application on a host. Actually, a port identifies a socket on a host. From Figure 1.2, we see fit the client-server
  model?
  2. To how many different kinds of networks is your home connected? How many support
  two-way transport?
  [] 1.6 Exercises
  Applications
  TCP sockets
  TCP ports 1
  ,- ..... '~ ..... -~. uDpSOCketsocketsreferences
  ....... Sockets bound to ports
  5535 UDPports
  UDP
  (" IP ")
  Figure 1.2: Sockets, protocols, and ports.
  3. IP is a best-effort protocol, requiring that i nformat i on be broken down into datagrams,
  which may be lost, duplicated, or reordered. TCP hides all of this, providing a reliable
  service that takes and delivers an unbroken st ream of bytes. How might you go about
  providing TCP service on top of IP? Why would anybody use UDP when TCP is available?
  chapt er2
  Basic Sockets
  You are now ready to learn about writing your own socket applications. We begin by
  demonstrating how Java applications identify network hosts. Then, we describe the creation
  of TCP and UDP clients and servers. Java provides a clear distinction between using TCP and
  UDP, defining a separate set of classes for bot h protocols, so we treat each separately.
  2.1 Socket Addresses
  IP specified in Java using a string that contains ei-
  ther the dotted-quad representation of the numeric address (e.g., 169.1.1.1) or a name (e.g.,
  server.example.corn). Java encapsulates the IP addresses abstraction in the InetAddress class
  which provides three static met hods for creating lnetAddress instances, getByName() and
  getAllByName () take a name or IP address and ret urn the corresponding InetAddress instance(s).
  For example, InetAddress.getByName("192.168.75.13") returns an instance identifying the IP
  address 192.168.75.13. The third method, getLocalHost (), returns an InetAddres s instance con-
  taining the local host address. Our first program example, InetAddressExample. java, demon-
  strates the use of InetAddress. The program takes a list of names or IP addresses as command-
  line parameters and prints the name and an IP address of the local host, followed by names
  and IP addresses of the hosts specified on the command line.
  InetAdd ressExam pie.java
  0 import java.net.*; // for InetAddress
  1
  2 public class InetAddressExample {
  3
  9
  ! O Chapter 2: Basic Sockets []
  7
  8
  9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  3O
  public static void main(String[] args) {
  // Get name and IP address of the local host
  try {
  InetAddress address = InetAddress.getLocalHost();
  System.out.println("Local Host:");
  System.out.println("\t" + address.getHostName());
  System.out.println("\t" + address.getHostAddress());
  } catch (UnknownHostException e) {
  System.out.println("Unable to determine this host's address");
  }
  for (int i = O; i < args.length; i++) {
  // Get name(s)/address(es) of hosts given on command line
  try {
  InetAddress[] addressList = InetAddress.getAllByName(args[i]);
  System.out.println(args[i] + ":");
  // Print the first name. Assume array contains at least one entry.
  System.out.println("\t" + addressList[O].getHostName());
  for (int j = O; j < addressList.length; j++)
  System.out.println("\t" + addressList[j].getHostAddress());
  } catch (UnknownHostException e) {
  System.out.println("Unable to find address for " + args[i]);
  }
  InetAddressExample.java
  1. Print i nf or mat i on about t he local host: lines 6-14
  Creat e an InetAddress i nst ance for the local host: line 8
  Print t he local host i nformat i on: lines 9-11
  getH0stName() and getH0stAddress() ret urn a string for the host name and IP address,
  respectively.
  2. Request i nf or mat i on for each host speci fi ed on the command line: lines 16-28
  Creat e an ar r ay of InetAddress i nst ances for t he speci fi ed host: line 19
  TnetAddress.getAllByName() ret urns an array of InetAddress instances, one for each
  of the specified host's addresses.
  Print t he host i nformat i on: lines 22-24
  To use this application to find i nformat i on about the local host and the publ i sher's Web server
  (), do the following:
  [] 2.1 Socket Addresses ! !
  % java InetAddressExample
  Local Host:
  t ract or.farm.com
  169.1.1.2:
  216.200.143.124
  If we know t he IP addr ess of a host (e.g., 169.1.1.1), we find t he name of t he host by
  % java InetAddressExample 169. i. i. 1
  Local Host:
  tractor, farm. com
  169.1.1.2
  169.1.1.1:
  base. farm. com
  169.1.I.i
  When the name service is not available for some reason--say, the program is running on
  a machi ne t hat is not connect ed to any net wor k- - at t empt i ng to i dent i fy a host by name may
  fail. Moreover, it may t ake a significant amount of t i me to do so, as t he syst em tries vari ous
  ways to resol ve t he name to an IP address. It is t her ef or e good to know t hat you can always
  refer to a host usi ng t he IP addr ess in dot t ed- quad not at i on. In any of our exampl es, if a r emot e
  host is speci fi ed by name, the host r unni ng t he exampl e mus t be confi gured to convert names
  to addr esses, or t he exampl e won't work. If you can pi ng a host usi ng one of its names (e.g.,
  r un t he command "ping server.example.corn"), t hen t he exampl es shoul d wor k wi t h names. If
  your pi ng t est fails or t he exampl e hangs, t ry speci fyi ng the host by IP address, whi ch avoi ds
  the name- t o- addr ess conver si on al t oget her.
  I net Address 1
  Creat ors
  st at i c I net Addr ess[ ] getAllByName(String host)
  Ret ur ns t he list of addr esses for t he speci fi ed host.
  host Host name or addr ess
  1For each Java networking class described in this text, we present only the primary methods and omit
  methods that are deprecated or whose use is beyond the scope of this text. As with everything in Java,
  the specification is a moving target. This information is included to provide an overall picture of the Java
  socket interface, not as a final authority. We encourage the reader to refer to the API specifications from
  java.sun.com as the current and definitive source.
  ! 2 Chapter 2: Basic Sockets []
  static Inet Address getByName(String host)
  static Inet Address getLocalHost0
  Returns an IP address for the specified/local host.
  host Host name or IP address
  Accessors
  byte[ ] getAddress0
  Returns the 4 bytes of the 32-bit IP address in big-endian order.
  String getHostAddress()
  Returns the IP address in dotted-quad notation (e.g., "169.1.1.2").
  String getHostName()
  Returns the canonical name of the host associated with the address.
  bool ean isMulticastAddress()
  Returns true if the address is a multicast address (see Section 4.3.2).
  Operators
  bool ean equals(Object address)
  Returns true if address is non-null and represents the same address as this $netAddress
  instance.
  address Address to compare
  2.2 TCP Sockets
  Java provides two classes for TCP: Socket and ServerSocket. An instance of Socket represents
  one end of a TCP connection. A TCP connection is an abstract two-way channel whose ends
  are each identified by an IP address and port number. Before being used for communication,
  a TCP connection must go t hrough a setup phase, which starts with the client's TCP sending a
  connection request to the server's TCP. An instance of ServerSocket listens for TCP connection
  requests and creates a new Socket instance to handle each incoming connection.
  2.2.1 TCPClient
  The client initiates communication with a server that is passively waiting to be contacted. The
  typical TCP client goes through three steps:
  1. Construct an instance of Socket: The constructor establishes a TCP connection to the
  specified remote host and port.
  [] 2.2 TCP Sockets 1 3
  2. Communi cat e usi ng the socket's I/O streams: A connect ed i nst ance of Socket cont ai ns
  an InputStream and 0utputStream that can be used j ust like any ot her Java I/O st ream (see
  Chapt er 3).
  3. Close the connect i on usi ng the cl ose( ) met hod of Socket.
  Our first TCP application, called TCPEchoClient.java, is a client t hat communi cat es with an
  echo s er ver usi ng TCP. An echo server simply repeat s what ever it receives back to the client.
  The string to be echoed is provi ded as a command-l i ne ar gument to our client. Many syst ems
  include an echo server for debuggi ng and testing purposes. To test if the st andar d echo server
  is running, try t el net t i ng to port 7 (the default echo port) on the server (e.g., at command line
  "t el net server, example, corn 7" or use your basic telnet application).
  TCPEchoClient.java
  5
  6
  7
  8
  9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  3O
  31
  0 import java.net.*; // for Socket
  1 import java.io.*; // for lOException and Input/OutputStream
  2
  3 public class rCPEchoClient {
  4
  public static void main(String[] args) throws IOException {
  if ((args.length < 2) II (args.length > 3)) // Test for correct # of args
  throw new lllegalArgumentException("Parameter(s): <Server> <Word> [<Port>]");
  String server = args[0]; // Server name or IP address
  // Convert input String to bytes using the default character encoding
  byte[] byteBuffer = args[l].getBytes();
  int servPort = (args.length == 3) ? Integer.parselnt(args[2]) : 7;
  // Create socket that is connected to server on specified port
  Socket socket = new Socket(server, servPort) ;
  System.out.println("Connected to server...sending echo string");
  InputStream in = socket, getlnputStream() ;
  OutputStream out = socket, getOutputStream() ;
  out.write(byteBuffer); // Send the encoded string to the server
  // Receive the same string back from the server
  int totalBytesRcvd = 0; // Total bytes received so far
  int bytesRcvd; // Bytes received in last read
  while (totalBytesRcvd < byteBuffer.length) {
  if ((bytesRcvd = in.read(byteBuffer, totalBytesRcvd,
  byteBuffer.length - totalBytesRcvd)) == -I)
  throw new SocketException("Connection closed prematurely");
  14 Chapter 2: Basic Sockets m
  32
  33
  34
  35
  36
  37
  38
  39
  }
  }
  totalBytesRcvd += bytesRcvd;
  }
  System.out.println("Received: " + new String(byteBuffer)) ;
  socket.close(); // Close the socket and its streams
  TCP Ec hoCI ie nt.ja va
  1. Application setup and parameter parsing: lines 0-14
  [] Convert the echo string: line 12
  TCP sockets send and receive sequences of bytes. The getBytes() met hod of String
  returns a byte array represent at i on of the string. (See Section 3.1 for a discussion of
  character encodings.)
  [] Determine the port of the echo server: line 14
  The default echo port is 7. If we specify a third parameter, I nt eger.par seI nt ( ) takes
  the string and returns the equivalent integer value.
  2. TCP socket creation: line 17
  The Socket constructor creates a socket and establishes a connection to the specified
  server, identified either by name or IP address. Note that the underlying TCP deals only
  with IP addresses. If a name is given, the i mpl ement at i on resolves it to the correspond-
  ing address. If the connection at t empt fails for any reason, the constructor throws an
  lOBxception.
  3. Get socket input and output streams: lines 20-21
  Associated with each connected Socket instance is an InputStream and 0utputStream. We
  send data over the socket by writing bytes to the 0utputStream just as we would any other
  stream, and we receive by reading from the InputStream.
  4. Send the string to echo server: line 23
  The wri t e() met hod of 0utputStream transmits the given byte array over the connection
  to the server.
  5. Receive the reply from the echo server: lines 25-33
  Since we know the number of bytes to expect from the echo server, we can repeatedly
  receive bytes until we have received the same number of bytes we sent. This particular
  form of read() takes three parameters: 1) buffer to receive into, 2) byte offset into the
  buffer where the first byte received should be placed, and 3) the maxi mum number of
  bytes to be placed in the buffer, read() blocks until some data is available, reads up
  to the specified maxi mum number of bytes, and returns the number of bytes actually
  placed in the buffer (which may be less than the given maximum). The loop simply fills
  [] 2.2 TCP Sockets 1 5
  up byteBuffer until we receive as many bytes as we sent. If the TCP connection is closed by
  the other end, read() returns -1. For the client, this indicates that the server prematurely
  closed the socket.
  Why not just a single read? TCP does not preserve read() and wri t e() message
  boundaries. That is, even t hough we sent the echo string with a single wri t e(), the echo
  server may receive it in multiple chunks. Even if the echo string is handled in one chunk
  by the echo server, the reply may still be broken into pieces by TCP. One of the most
  common errors for beginners is the assumpt i on that data sent by a single wri t e() will
  always be received in a single read ().
  6. Print echoed string: line 35
  To print the server's response, we must convert the byte array to a string using the default
  character encoding.
  7. Close socket: line 37
  When the client has finished receiving all of the echoed data, it closes the socket.
  We can communicate with an echo server named server.example.com with IP address
  169.1.1.1 in either of the following ways:
  % java TCPEchoClient server.example.com "Echo this!"
  Received: Echo this!
  % java TCPEchoClient 169. i. i. 1 "Echo this!"
  Received: Echo this!
  See TCPEchoClientGUI. java on the book's Web site for an implementation of the TCP echo client
  with a graphical interface.
  Socket
  Const ruct ors
  Socket(InetAddress remoteAddr, int remotePort)
  Socket(String remoteHost, int remotePort)
  Socket(InetAddress remoteAddr, int remotePort, Inet Address localAddr, int localPort)
  Socket(String remoteHost, int remotePort, Inet Address localAddr, int localPort)
  Constructs a TCP socket connected to the specified remote address and port. The first
  two forms of the constructor do not specify the local address and port, so a default
  local address and some available port are chosen. Specifying the local address may be
  useful on a host with multiple interfaces.
  remoteAddr Remote host address
  remoteHost Remote host name or IP address (in dotted-quad form)
  remotePort Remote port
  16 Chapter 2: Basic Sockets []
  localAddr
  localPort
  Local address; use null to specify using the default local
  address
  Local port; a localPort of 0 allows the constructor to pick any
  available port
  Operat ors
  voi d close()
  Closes the TCP socket and its I/O streams.
  void shutdownTnput()
  Closes the input side of a TCP stream. Any unread data is silently discarded, including
  data buffered by the socket, data in transit, and data arriving in the future. Any subse-
  quent at t empt to read from the socket will ret urn end-of-stream (-1); any subsequent
  call to getlnputStream() will cause an lOException to be thrown (see Section 4.5).
  voi d shutdown0utput()
  Closes the out put side of a TCP stream. The i mpl ement at i on will at t empt to deliver any
  data already written to the socket's output st ream to the other end. Any subsequent
  at t empt to write to the socket's out put st ream or to call get0utputStream() will cause
  an IOException to be thrown (see Section 4.5).
  Accessors/Mutators
  InetAddress getlnetAddress()
  int getPort()
  Returns the remote socket address/port.
  InputStream getlnputStream0
  OutputStream get0utputStream0
  Returns a st ream for reading/writing bytes from/t o the socket.
  boolean getKeepAlive()
  void setKeepAlive(boolean on)
  Ret urns/set s keepalive message behavior. If keepalive is enabled, TCP sends a probe
  to the other end of the connection when no data has been exchanged for a system-
  dependent amount of time (usually two hours). If the remote socket is still alive, it
  will acknowledge the probe (invisible to the application). However, if the other end
  fails to acknowledge several probes in a row, the local TCP closes the connection, and
  subsequent operations on it will throw an exception. Keepalive is disabled by default.
  on If true (false), enable (disable) keepalive.
  [] 2.2 TCP Sockets |
  InetAddress getLocalAddress()
  int getLocalPort()
  Returns the local socket address/port.
  int getReceiveBufferSize()
  int getSendBufferSize()
  void setReceiveBufferSize(int size)
  void setSendBufferSize(int size)
  Returns/sets the size of the send/receive buffer for the socket (see Section 4.4).
  size Number of bytes to allocate for the socket send/receive
  buffer
  int getSoLinger()
  voi d setSoLinger(boolean on, int linger)
  Ret urns/set s the maxi mum amount of time (in milliseconds) that cl ose() will block
  waiting for all data to be delivered, getSoLinger() returns -1 if lingering is disabled
  (see Section 5.4). Lingering is off by default.
  on If true, the socket lingers on close(), up to the maxi mum
  specified time.
  linger The maxi mum amount of time (milliseconds) a socket lingers
  on close()
  int getSoTimeout()
  voi d setSoTimeout(int t i meout )
  Ret urns/set s the maxi mum amount of time that a read() on this socket will block. If
  the specified number of milliseconds elapses before any data is available, an I nt er -
  ruptedIOException is thrown (see Section 4.2).
  t i meout The maxi mum time (milliseconds) to wait for data on a
  read(). The value 0 (the default) indicates that there is no
  time limit, meaning that a read will not ret urn until data is
  available.
  boolean getTcpNoDelay()
  void setTcpNoDelay(boolean on)
  Returns/sets whether the Nagle algorithm to coalesce TCP packets is disabled. To avoid
  small TCP packets, which make inefficient use of network resources, Nagle's algorithm
  (enabled by default) delays packet t ransmi ssi on under certain conditions to improve
  the opportunities to coalesce bytes from several writes into a single TCP packet. This
  delay is unacceptable to some types of interactive applications.
  on If true (false), disable (enable) Nagle's algorithm.
  1 8 Chapter 2: Basic Sockets m
  Caveat: By default, Socket is implemented on top of a TCP connection; however, in Java,
  you can actually change the underlying implementation of Socket. This book is about TCP/IP,
  so for simplicity we assume that the underlying implementation for all of the these networking
  classes is the default.
  2.2.2 TCP Server
  We now turn our attention to constructing a server. The server's job is to set up a communi-
  cation endpoint and passively wait for connections from clients. The typical TCP server goes
  t hrough two steps:
  1. Construct a ServerSocket instance, specifying the local port. This socket listens for
  incoming connections to the specified port.
  2. Repeatedly:
  Call the accept () met hod of ServerSocket to get the next incoming client connection.
  Upon establishment of a new client connection, an instance of Socket for the new
  connection is created and returned by accept ().
  Communicate with the client using the ret urned Socket's InputStream and Output-
  Stream.
  Close the new client socket connection using the close() met hod of Socket.
  Our next example, TCPEchoServer. java, implements the echo service used by our client
  program. The server is very simple. It runs forever, repeatedly accepting a connection, receiving
  and echoing bytes until the connection is closed by the client, and then closing the client socket.
  TCPEchoServer.java
  0 import java.net.* ; // for Socket, ServerSocket, and InetAddress
  1 import java.io.*; // for IOException and Input/0utputStream
  2
  3 public class TCPEchoServer {
  4
  5
  6
  7
  8
  9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  private static final int BUFSIZE = 32; // Size of receive buffer
  public static void main(String[] args) throws lOException {
  if (args.length != i) // Test for correct # of args
  throw new lllegalArgumentException("Parameter(s): <Port>");
  int servPort = Integer. parselnt (args [0 ] ) ;
  // Create a server socket to accept client connection requests
  ServerSocket servSock = new ServerSocket(servPort) ;
  int recvMsgSize; // Size of received message
  byte[] byteBuffer = new byte[BUFSlZE]; // Receive buffer
  m 2.2 TCP Sockets 19
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  }
  }
  for (;;) { // Run forever, accepting and servicing connections
  Socket clntSock = servSock.accept() ; // Get client connection
  System.out.println("Handling client at " +
  clntSock.getInetAddress().getHostAddress() + " on port "+
  clntSock, getPort ()) ;
  InputStream in = clntSock, getlnputStream() ;
  OutputStream out = clntSock.getOutputStream() ;
  // Receive until client closes connection, indicated by-i return
  while ((recvMsgSize = in.read(byteBuffer)) != -I)
  out.write(byteBuffer, O, recvMsgSize) ;
  clntSock, close () ;
  }
  /* NOT REACHED */
  // Close the socket.
  We are done with this client!
  TCPEchoServer.java
  1. Appl i cat i on setup and par amet er parsing: lines 0-12
  2. Server socket creation: line 15
  servSock listens for client connection requests on the port specified in the constructor.
  3. Loop forever, i t erat i vel y handl i ng i ncomi ng connections" lines 20-35
  Accept an i ncomi ng connection: line 21
  The sole purpose of a ServerSocket instance is to supply a new, connected Socket
  instance for each new TCP connection. When the server is ready to handle a client, it
  calls accept (), which blocks until an incoming connection is made to the ServerSocket's
  port. accept() then ret urns an instance of Socket that is already connected to the
  remote socket and ready for reading and writing.
  Report connect ed client: lines 23-25
  We can query the newly created Socket instance for the address and port of the
  connecting client. The get l net Address() met hod of Socket returns an instance of
  InetAddress containing the address of the client. We call getHostAddress() to ret urn
  the IP address as a dotted-quad String. The get Port () met hod of Socket ret urns the
  port of the client.
  Get socket input and output st reams: lines 27-28
  Bytes written to this socket's 0utputStream will be read from the client's socket's
  InputStream, and bytes written to the client's 0utputStream will be read from this
  socket's InputStream.
  20 Chapter 2: Basic Sockets []
  Receive and repeat data until the client closes: lines 30-32
  The while loop repeatedly reads bytes (when available) from the input st ream and
  immediately writes the same bytes back to the output st ream until the client closes
  the connection. The read() met hod of InputStream reads up to the maxi mum number
  of bytes the array can hold (in this case, BUFSIZE bytes) into the byte array (byteBuffer)
  and ret urns the number of bytes read. read () blocks until data is available and ret urns
  -1 if there is no data available, indicating that the client closed its socket. In the echo
  protocol, the client closes the connection when it has received the number of bytes
  back that it sent, so in the server we expect to receive a -1 from read(). Recall that in
  the client, receiving a -1 from read() indicates an error because it indicates that the
  server premat urel y closed the connection.
  As previously mentioned, read() does not have to fill the entire byte array to
  return. In fact, it can ret urn after having read only a single byte. The wri t e() met hod
  of 0utputStream writes recvMsgSize bytes from byteBuffer to the socket. The second
  paramet er indicates the offset into the byte array of the first byte to send. In this case,
  0 indicates to take bytes starting from the front of byteBuffer. If we had used the
  form of wri t e() that takes only the buffer argument, all the bytes in the buffer array
  would have been transmitted, possibly including bytes that were not received from
  the client!
  Close client socket: line 34
  ServerSocket
  Const ruct ors
  ServerSocket(int localPort)
  ServerSocket(int localPort, int queueLimit)
  ServerSocket(int localPort, int queueLimit, InetAddress localAddr)
  Construct a TCP socket that is ready to accept incoming connections to the specified
  local port. Optionally, the size of the connection queue and the local address can be
  set.
  localPort Local port. A port of 0 allows the constructor to pick any
  available port.
  queueLimit The maxi mum size of the queue of incomplete connections
  and sockets waiting to be accept()ed. If a client connection
  request arrives when the queue is full, the connection is
  refused. Note that this may not necessarily be a hard lirrdt.
  For most platforms, it cannot be used to precisely control
  client population.
  m 2.2 TCP Sockets 21
  localAddr
  The IP address to which connections to this socket should be
  addressed (must be one of the local interface addresses). If the
  address is not specified, the socket will accept connections to
  any of the host's IP addresses. This may be useful for hosts
  with multiple interfaces where the server socket should only
  accept connections on one of its interfaces.
  Operators
  Socket accept()
  Returns a connected Socket instance for the next new incoming connection to the
  server socket. If no established connection is waiting, accept() blocks until one is
  established or a timeout occurs (see setSoTimeout()).
  void close()
  Closes the underlying TCP socket. After invoking this method, incoming client con-
  nection requests for this socket are rejected.
  Accessors/Mutators
  Inet Address getlnetAddress ()
  int getLocalPort()
  Returns the local address/port of the server socket.
  int getSoTimeoutO
  voi d setSoTimeout(int timeout)
  Ret urns/set s the maxi mum amount of time (in milliseconds) that an accept() will
  block for this socket. If the timer expires before a connection request arrives, an
  InterruptedlOException is thrown. A timeout value of 0 indicates no timeout: calls
  to accept () will not return until a new connection is available, regardless of how much
  time passes (see Section 4.2).
  2.2.3 Input and Out put Streams
  As illustrated by the examples above, the primary paradigm for I/O in Java is the stream
  abstraction. A stream is simply an ordered sequence of bytes. Java input streams support
  reading bytes, and output streams support writing bytes. In our TCP client and server, each
  Socket instance holds an InputStream and an 0utputStream instance. When we write to the
  out put stream of a Socket, the bytes can (eventually) be read from the input stream of the
  Socket at the other end of the connection.
  0utputStream is the abstract superclass of all out put streams in Java. Using an Output-
  Stream, we can write bytes to, flush, and close the out put stream.
  22 Chapter 2: Basic Sockets II
  OutputStream
  data
  offset
  length
  voi d flush()
  abstract voi d write(int data)
  Writes a single byte to the out put stream.
  data Byte (low-order 8 bits) to write to output st ream
  voi d wri t e(byt e[] data)
  Writes entire array of bytes to the output stream.
  data Bytes to write to out put st ream
  voi d write(byte[ ] data, int offset, int length)
  Writes length bytes from data starting from byte offset.
  Bytes from which to write to out put st ream
  Starting byte to send in data
  Number of bytes to send
  Pushes any buffered data out to the stream.
  voi d close()
  Terminates the stream.
  InputStream is the abstract superclass of all input streams. Using an InputStream, we can
  read bytes from and close the input stream.
  InputStream
  abst ract int read()
  Read and ret urn a single byte from the input stream. The byte read is in the least
  significant byte of the ret urned integer. This met hod returns -1 on end-of-stream.
  int read(byte[] data)
  Reads up to data.length bytes (or until the end-of-stream) from the input st ream into
  data and returns the number of bytes read. If no data is available, read () blocks until
  at least I byte can be read or the end-of-stream is detected, indicated by a ret urn of -1.
  data Buffer to receive data from input st ream
  int read(byte[ ] data, int offset, int length)
  Reads up to length bytes (or until the end-of-stream) from the input st ream into
  data, starting at position offset, and returns the number of bytes read. If no data
  [] 2.3 UDP Sockets 23
  is available, read() blocks until at least 1 byte can be read or the end-of-stream is
  detected, indicated by a return of -1.
  data Buffer to receive data from input stream
  offset Starting byte of data in which to write
  length Maximum number of bytes to read
  int available()
  Returns the number of bytes available for input.
  void close()
  Terminates the stream.
  2 different characteristics from the TCP t o/from any address and
  t o/from many different addresses in succession.
  Another difference between UDP sockets and TCP sockets is the way that they deal with
  message boundaries: UDP sockets preserve them. This makes receiving an application message
  simpler, in some ways, than it is with TCP sockets. (This is discussed further in Section 2.3.4.) A
  final difference is that the end-to-end t ransport service UDP provides is best-effort: there is no
  guarantee that a message sent via a UDP socket will arrive at its destination, and messages can
  be delivered in a different order than they were sent Oust like letters sent t hrough the mail).
  A program using UDP sockets must therefore be prepared to deal with loss and reordering.
  (We'll provide an example of this later.)
  Given this additional burden, why would an application use UDP instead of TCP? One
  reason is efficiency: flexibility:
  when something other than a reliable byte-stream service is required, UDP provides a minimal-
  overhead platform on which to implement whatever is needed.
  Java programmers use UDP sockets via the classes DatagramPacket and DatagramSocket.
  Both clients and servers use DatagramSockets to send and receive DatagramPackets.
  24 Chapter 2: Basic Sockets []
  2.3.1 DatagramPacket
  Instead of sending and receiving streams of bytes as with TCP, UDP endpoints exchange
  self-contained messages, called datagrams, which are represented in Java as instances of
  DatagramPacket. To send, a Java program constructs a DatagramPacket instance and passes it as
  an argument to the send() method of a DatagramSocket. To receive, a Java program constructs
  a DatagramPacket instance with preallocated space (a byte[ ]), into which the contents of a
  received message can be copied (if/when one arrives), and then passes the instance to the
  receive () met hod of a DatagramSocket.
  In addition to the data, each instance of DatagramPacket also contains address and port
  information, the semantics of which depend on whether the datagram is being sent or received.
  When a DatagramPacket is sent, the address and port identify the destination; for a received
  DatagramPacket, they identify the source of the received message. Thus, a server can receive
  into a DatagramPacket instance, modify its buffer contents, then send the same instance, and
  the modified message will go back to its origin. Internally, a DatagramPacket also has length
  and offset fields, which describe the location and number of bytes of message data inside the
  associated buffer. See the following reference and Section 2.3.4 for some pitfalls to avoid when
  using DatagramPackets.
  Datag ram Packet
  Const ruct ors
  DatagramPacket(byte[ ] buffer, int length)
  DatagramPacket(byte[ ] buffer, int offset, int length)
  DatagramPacket(byte[ ] buffer, int length, Inet Address remoteAddr, int remotePort)
  DatagramPacket(byte[] buffer, int offset, int length, Inet Address remoteAddr, int re-
  motePort)
  Constructs a datagram and makes the given byte array its data buffer. The first two
  forms are typically used to construct DatagramPackets for receiving because the desti-
  nation address is not specified (although it could be specified later with setAddress()
  and setPort ()). The second two forms are typically used to construct DatagramPackets
  for sending.
  buffer Datagram payload
  length Number of bytes of the buffer that will actually be used.
  If the datagram is sent, length bytes will be transmitted. If
  receiving into this datagram, length specifies the maxi mum
  number of bytes to be placed in the buffer.
  offset Location in the buffer array of the first byte of message data
  to be sent/received; defaults to 0 if unspecified.
  [] 2.3 UDP Sockets 2 5
  remoteAddr
  remotePort
  Address (typically destination) of the datagram
  Port (typically destination) of the datagram
  Accessors/Mutators
  InetAddress getAddress()
  voi d setAddress(InetAddress address)
  Returns/sets the datagram address. There are other ways to set the address: 1) the
  address of a DatagramPacket instance can also be set by the constructor, and 2)
  the receive() method of DatagramSocket sets the address to the datagram sender's
  address.
  address Datagram address
  int getPort()
  voi d setPort(int port)
  Returns/sets the datagram port. There are other ways to set the address: 1) the port
  can be explicitly set by the constructor or the setPort() method, and 2) the receive()
  method of DatagramSocket sets the port to the datagram sender's port.
  port Datagram port
  int getT.ength()
  voi d setLength(int length)
  Returns/sets the internal length of the datagram. The internal datagram length can be
  set explicitly by the constructor or by the setLength() method. Attempting to make it
  larger than the length of the associated buffer results in an IllegalArgumentException.
  The receive() method of DatagramSocket uses the internal length in two ways: 1) on
  input, it specifies the maximum number of bytes of a received message that will be
  copied into the buffer, and 2) on return, it indicates the number of bytes actually placed
  in the buffer.
  length Length in bytes of the usable portion of the buffer
  int get0ffset()
  Returns the location in the buffer of the first byte of data to be sent/received. There
  is no set 0ffset () method; however, it can be set with setData().
  byte[] getDataO
  Returns the buffer associated with the datagram. The returned object is a reference
  to the byte array that was most recently associated with this DatagramPacket, either
  by the constructor or by setData(). The length of the returned buffer may be greater
  than the internal datagram length, so the internal length and offset values should be
  used to determine the actual received data.
  26 Chapter 2: Basic Sockets []
  void setData(byte[] buffer)
  void setData(byte[] buffer, int offset, int length)
  Makes the given byte array the datagram buffer. The first form makes the entire byte
  array the buffer; the second form makes bytes offset through offset + length- 1 the
  buffer. The first form never updates the internal offset and only updates the internal
  length if the given buffer's length is less than the current internal length. The second
  form always updates the internal offset and length.
  buffer Preallocated byte array for datagram packet data
  offset Location in buffer where first byte is to be accessed
  length Number of bytes to be read from/written into buffer
  2.3.2 UDPClient
  A UDP client begins by sending a datagram to a server that is passively waiting to be contacted.
  The typical UDP client goes through three steps:
  1. Construct an instance of DatagramSocket, optionally specifying the local address and port.
  2. Communicate by sending and receiving instances of DatagramPacket using the send() and
  receive() methods of DatagramSocket.
  3. When finished, deallocate the socket using the close() method of DatagramSocket.
  Unlike a Socket, a DatagramSocket is not constructed with a specific destination address.
  This illustrates one of the major differences between TCP and UDP. A TCP socket is required to
  establish a connection with another TCP socket on a specific host and port before any data can
  be exchanged, and, thereafter, it only communicates with that socket until it is closed. A UDP
  socket, on the other hand, is not required to establish a connection before communication, and
  each datagram can be sent to or received from a different destination. (The connect () method
  of DatagramSocket does allow the specification of the remote address and port, but its use is
  optional.)
  Our UDP echo client, UDPEchoClientTimeout. java, sends a datagram containing the string
  to be echoed and prints whatever it receives back from the server. A UDP echo server simply
  repeats each datagram that it receives back to the client. Of course, a UDP client only commu-
  nicates with a UDP server. Many systems include a UDP echo server for debugging and testing
  purposes. on
  read () waiting for a reply. If we try the same strategy with our UDP echo client and the echo
  request datagram is lost, our client will block forever on receive (). To avoid this problem, our
  client specifies a maximum amount of time to block on receive(), after which it tries again by
  resending the echo request datagram. Our echo client performs the following steps:
  [] 2.3 UDP Sockets 2 7
  1. Send the echo st ri ng to t he server.
  2. Block on r ecei ve( ) for up to t hree seconds, st art i ng over (up to five times) if the repl y is
  not recei ved before t he t i meout.
  3. Ter mi nat e t he client.
  UDPEchoClientTimeout.java
  O import java.net.*;
  1 import java.io.*; // for lOBxception
  2
  3 public class UDPEchoClientTimeout {
  4
  5
  6
  7
  8
  9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  // for DatagramSocket, DatagramPacket, and InetAddress
  private static final int TIMEOUT = 3000;
  private static final int MAXTRIBS = 5;
  // Resend timeout (milliseconds)
  // Maximum retransmissions
  public static void main(String[] args) throws lOException {
  if ((args.length < 2) I I (args.length > 3)) // Test for correct # of args
  throw new lllegalArgumentException("Parameter(s)' <Server> <Word> [<Port>]");
  InetAddress serverAddress = InetAddress.getByName(args[0]); // Server address
  // Convert the argument String to bytes using the default encoding
  byte[] bytesZoSend = args[l].getBytes();
  int servPort = (args.length == 3) ? Integer.parselnt(args[2]) 7;
  DatagramSocket socket = new DatagramSocket() ;
  socket.setSoTimeout(TIMEOUT); // Maximum receive blocking time (milliseconds)
  DatagramPacket sendPacket = new DatagramPacket(bytesToSend,
  bytesToSend.length, serverAddress, servPort) ;
  // Sending packet
  DatagramPacket receivePacket = // Receiving packet
  new DatagramPacket(new byte[bytesToSend.length], bytesToSend.length);
  int tries = 0; // Packets may be lost, so we have to keep trying
  boolean receivedResponse = false;
  do {
  socket.send(sendPacket); // Send the echo string
  try {
  socket.receive(receivePacket); // Attempt echo reply reception
  if (!receivePacket.getAddress().equals(serverAddress)) // Check source
  throw new lOException("Received packet from an unknown source");
  receivedResponse = true;
  28 Chapter 2: Basic Sockets []
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  }
  }
  } catch (InterruptedlOException e) { // We did not get anything
  tries += I;
  System.out.println("Timed out, " + (~TRIES - tries) + " more tries...") ;
  }
  } while ((!receivedResponse) && (tries < ~s ;
  if (receivedResponse)
  System.out.println("Received: " + new String(receivePacket.getData()));
  else
  System. out.println("No response -- giving up.") ;
  socket.close();
  UDPEchoClientTimeout.java
  1. Application setup and parameter parsing: lines 0-17
  Convert argument to bytes: line 15
  2. UDP socket creation: line 19
  This instance of DatagramSocket can send dat agrams to any UDP socket. We do not specify
  a local address or port so some local address and available port will be selected. We can
  explicitly set t hem with the setLocalAddress() and set Local Port () met hods or in the
  constructor.
  3. Set the socket timeout: line 21
  The timeout for a dat agram socket controls the maxi mum amount of time (milliseconds)
  a call to recei ve() will block. Here we set the timeout to three seconds. Note that timeouts
  are not precise: the call may block for more than the specified time (but not less).
  4. Create dat agr am to send: lines 23-24
  To create a dat agram for sending, we need to specify three things: data, destination
  address, and destination port. For the destination address, we may identify the echo
  server either by name or IP address. If we specify a name, it is converted to the actual IP
  address in the constructor.
  5. Create dat agr am to receive: lines 26-27
  To create a dat agram for receiving, we only need to specify a byte array to hold the
  dat agram data. The address and port of the dat agram source will be filled in by receive ().
  6. Send the datagram: lines 29-44
  Since dat agrams may be lost, we must be prepared to ret ransmi t the datagram. We loop
  sending and at t empt i ng a receive of the echo reply up to five times.
  Send the datagram: line 32
  send() t ransmi t s the dat agram to the address and port specified in the datagram.
  II 2.3 UDP Sockets 29
  Handle dat agr am reception: lines 33-43
  recei ve() blocks until it either receives a dat agram or the timer expires. Timer expi-
  ration is indicated by an InterruptedlOException. If the timer expires, we increment
  the send at t empt count (tries) and start over. After the maxi mum number of tries,
  the while loop exits without receiving a datagram. If recei ve() succeeds, we set the
  loop flag receivedResponse to true, causing the loop to exit. Since packets may come
  from anywhere, we check the source address of the recieved dat agram to verify that
  it mat ches the address of the specified echo server.
  7. Print recept i on results: lines 46-49
  If we received a datagram, receivedResponse is true, and we can print the dat agram data.
  8. Close the socket: line 51
  We invoke the UDP client using the same paramet ers as used in the TCP client.
  DatagramSocket
  Constructors
  DatagramSocket()
  DatagramSocket(int localPort)
  DatagramSocket(int localPort, Inet Address localAddr)
  Constructs a UDP socket. Either or bot h the local port and address may be specified.
  If the local port is not specified, the socket is bound to any available local port. If the
  local address is not specified, one of the local addresses is chosen.
  localPort Local port; a localPort of 0 allows the constructor to pick any
  available port.
  localAddr Local address
  Operators
  voi d close()
  After closing, dat agrams may no longer be sent or received using this socket.
  voi d connect(InetAddress remoteAddr, int remotePort)
  Sets the remote address and port of the socket. Attempting to send dat agrams with
  a different address will cause an exception to be thrown. The socket will only receive
  dat agrams from the specified port and address. Datagrams from any other port or
  address are ignored. This is strictly a local operation because there is no end-to-end
  connection. Caveat: A socket that is connected to a multicast or broadcast address can
  30 Chapter 2: Basic Sockets []
  only send datagrams, because a datagram source address is always a unicast address
  (see Section 4.3).
  remoteAddr Remote address
  remotePort Remote port
  void disconnect()
  Removes the remote address and port specification of the socket (see connect()).
  void receive(DatagramPacket packet)
  Places data from the next received message into the given DatagramPacket.
  packet Receptacle for received information, including source
  address and port as well as message data. (See the
  DatagramPacket reference for details of semantics.)
  void send(DatagramPacket packet)
  Sends a datagram from this socket.
  packet Specifies the data to send and the destination address and
  port. If packet does not specify a destination address, the
  DatagramSocket must be "connected" to a remote address
  and port (see connect ()).
  Accessors/Mutatots
  InetAddress getlnetAddressO
  int getPort0
  Returns the remote socket address/port.
  InetAddress getLocalAddress0
  int getLocalPort0
  Returns the local socket address/port.
  int getReceiveBufferSize0
  int getSendBufferSize0
  void setReceiveBufferSize(int size)
  void setSendBufferSize(int size)
  The DatagramSocket has limits on the maximum datagram size that can be sent/
  received through this socket. The receive limit also determines the amount of message
  data that can be queued waiting to be returned via receive(). That is, when the amount
  of buffered data exceeds the limit, arriving packets are quietly discarded. Setting the
  size is only a hint to the underlying implementation. Also, the semantics of the limit
  may vary from system to system: it may be a hard limit on some and soft on others.
  size Desired limit on packet and/or queue size (bytes)
  II 2.3 UDP Sockets 31
  int getSoTimeout()
  voi d setSoTimeout(int timeout)
  Ret urns/set s the maxi mum amount of time that a receive () will block for this socket.
  If the specified time elapses before data is available, an InterruptedlOException is
  thrown.
  timeout The maxi mum amount of time (milliseconds) that recei ve()
  will block for the socket. A timeout of 0 indicates that a
  receive will block until data is available.
  2.3.3 UDPServer
  Like a TCP server, a UDP server's job is to set up a communi cat i on endpoint and passively
  wait for the client to initiate the communication; however, since UDP is connectionless, UDP
  communication is initiated by a dat agram from the client, without going t hrough a connection
  setup as in TCP. The typical UDP server goes t hrough four steps:
  1. Construct an instance of DatagramSocket, specifying the local port and, optionally, the
  local address. The server is now ready to receive dat agrams from any client.
  2. Receive an instance of DatagramPacket using the recei ve() met hod of DatagramSocket.
  When recei ve() returns, the dat agram contains the client's address so we know where
  to send the reply.
  3. Communicate by sending and receiving DatagramPackets using the send() and recei ve()
  met hods of DatagramSocket.
  4. When finished, deallocate the socket using the cl ose() met hod of DatagramSocket.
  Our next program example, UDPEchoServer. java, i mpl ement s the UDP version of the echo
  server. The server is very simple: it loops forever, receiving dat agrams and then sending the
  same dat agrams back to the client. Actually, our server only receives and sends back the first
  255 (ECHOMAX) characters of the datagram; any excess is silently discarded by the socket
  i mpl ement at i on (see Section 2.3.4).
  U D P Ec h oSe rye r .ja va
  O import java.net.*; // for DatagramSocket, DatagramPacket, and InetAddress
  1 import j ava.i o.*; // for IOException
  2
  3 public class UDPEchoServer {
  4
  5 private st at i c final int ECHO~X = 255; // Maximum size of echo datagram
  32 Chapter 2: Basic Sockets I
  6
  7
  8
  9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  public static void main(String[] args) throws lOF, xception {
  if (args.length != i) // Test for correct argument list
  throw new lllegalArgumentException("Parameter(s) : <Port>") ;
  int servPort = Integer.parselnt(args[O]);
  DatagramSocket socket = new DatagramSocket (servPort) ;
  DatagramPacket packet = new DatagramPacket(new byte[ECHOMAX], ECHOMAX);
  for (;;) { // Run forever, receiving and echoing datagrams
  socket.receive(packet); // Receive packet from client
  System.out.println("Handling client at " +
  packet.getAddress().getHostAddress() + " on port " + packet.getPort());
  socket.send(packet); // Send the same packet back to client
  packet.setLength(ECHOMAX); // Reset length to avoid shrinking buffer
  }
  /* NOT REACHED */
  U D P Ec h oSe rye r .ja va
  1. Application setup and parameter parsing: lines 0-12
  UDPEchoServer takes a single paramet er, the local port of the echo server socket.
  2. Create and set up datagram socket: line 14
  Unlike our UDP client, a UDP server must explicitly set its local port to a number known
  by the client; otherwise, the client will not know the dest i nat i on port for its echo request
  dat agram. When the server receives the echo dat agr am from the client, it can find out the
  client's address and port from the dat agram.
  3. Create datagram: line 15
  UDP messages are cont ai ned in dat agrams. We const ruct an i nst ance of DatagramPacket
  with a buffer of ECHOMAX (255) bytes. This dat agr am will be used bot h to receive the echo
  r equest and to send the echo reply.
  4. Iteratively handle incoming echo requests: lines 17-23
  The UDP server uses a single socket for all communi cat i on, unlike the TCP server, whi ch
  creat es a new socket with every successful accept ().
  Receive an echo request datagram: lines 18-20
  The r ecei ve( ) met hod of DatagramSocket blocks until a dat agr am is received f r om a
  client (unless a t i meout is set). There is no connection, so each dat agr am may come
  [] 2.3 UDP Sockets ~
  from a different sender. The dat agram itself contains the sender's (client's) source
  address and port.
  Send echo reply: line 21
  packet already contains the echo string and echo reply destination address and port,
  so the send() met hod of DatagramSocket can simply t ransmi t the dat agram previously
  received. Note that when we receive the datagram, we interpret the dat agram address
  and port as the source address and port, and when we send a datagram, we interpret
  the dat agram's address and port as the destination address and port.
  Reset buffer size: line 22
  The internal length of packet was set to the length of the message just processed,
  which may have been smaller than the original buffer size. If we do not reset the
  internal length before receiving again, the next message will be t runcat ed if it is longer
  than the one j ust received.
  2.3.4 Sending and Receiving with UDP Sockets
  A subtle but i mport ant difference between TCP and UDP is that UDP preserves message
  boundaries. Each call to recei ve() returns data from at most one call to send() Moreover,
  different calls to recei ve() will never ret urn data from the same call to send().
  When a call to wri t e() on a TCP socket's out put st ream returns, all the caller knows is
  that the data has been copied into a buffer for transmission; the data may or may not have
  actually been t ransmi t t ed t ransmi ssi on and is (or soon will be) on its way out the
  door.
  Between the time a message arrives from the network and the time its data is ret urned via
  read() or recei ve(), the data is stored in a first-in, first recei ve() will never ret urn more than
  one message. However, if recei ve() is called with a DatagramPacket containing a buffer of size
  n, and the size of the first message in the receive queue exceeds n, only the first n bytes of
  the message are returned. The remaining bytes are quietly discarded, with no indication to the
  receiving program that information has been lost!
  For this reason, a receiver should always supply a DatagramPacket with a buffer big enough
  to hold the largest message allowed by its application protocol at the time it calls recei ve().
  This technique will guarantee that no data will be lost. The maxi mum amount of data that can
  be t ransmi t t ed in a DatagramPacket is 65,507 byt es--t he largest payload that can be carried in
  a UDP datagram. It is i mport ant to remember here that each instance of DatagramPacket has an
  internal notion of message length that may be changed whenever a message is received into
  34 Chapter 2: Basic Sockets []
  that instance (to reflect the number of bytes in the received message). Applications that call
  receive() more than once with the same instance of DatagramPacket should explicitly reset the
  internal length to the actual buffer length before each subsequent call to receive().
  Another potential source of problems for beginners is the getData() method of Data-
  gramPacket, which always returns the entire original buffer, ignoring the internal offset and
  length values. Receiving a message into the DatagramPacket only modifies those locations of
  the buffer into which message data was placed. For example, suppose buf is a byte array of
  size 20, which has been initialized so that each byte contains its index in the array:
  0 ] 1 I 2 I 3 I 4 I 5101 ~ I ~ I 9 I 10111112113114115116117118119 I
  Suppose also that dg is a DatagramPacket, and that we set dg's buffer to be the middle 10 bytes
  of buf :
  dg. setData(buf, 5,10) ;
  Now suppose that dgsocket is a DatagramSocket, and that somebody sends an 8-byte message
  containing
  I 41 I 42 143 I 44 I 45 I 46 I 47148 I
  to dgsocket. The message is received into dg:
  dgsocket .receive(dg) ;
  Now, calling dg. getData() returns a reference to the original byte array buf, whose contents
  are now
  0 I 11 2 I 3 I 4 I 411 421 431 441 451 461 471 481 131 141 151 161 171 181 19 I
  Note that only bytes 5-12 of buf have been modified and that, in general, the application
  needs to use get 0ffset () and getData() to access just the received data. One possibility is to
  copy the received data into a separate byte array, like this:
  byte[] destBuf = new byte[dg.getLength()];
  System.arraycopy(dg.getData(), dg.getOffset(), destSuf, O, destSuf.length);
  2.4 Exercises
  1. For TCPF.choServer. java, we explicitly specify the port to the socket in the constructor.
  We said that a socket must have a port for communication, yet we do not specify a port
  in TCPY.choClient. java. How is the echo client's socket assigned a port?
  2. When you make a phone call, it is usually the callee that answers with "Hello." What
  changes to our client and server examples would be needed to implement this?
  3. What happens if a TCP server never calls accept()? What happens if a TCP client sends
  data on a socket that has not yet been accept ()ed at the server?
  [] 2.4 Exercises ~
  4. Servers are supposed to run for a long time without stopping--therefore, they must be
  designed to provide good service no mat t er what their clients do. Examine the server
  examples (TCPEchoServer. java and UDPEchoServer. java) and list anything you can think
  of that a client might do to cause it to give poor service to other clients. Suggest
  i mprovement s to fix the problems that you find.
  5. Modify TCPEchoServer. java to read and write only a single byte at a time, sleeping one
  second between each byte. Verify that TCPEchoClient.java requires multiple reads to
  successfully receive the entire echo string, even t hough it sent the echo string with one
  wri t e().
  6. Modify TCPEchoServer. java to read and write a single byte and then close the socket.
  What happens when the TCPEchoClient sends a multibyte string to this server? What is
  happening? (Note that the response could vary by OS.)
  7. Modify UDPEchoServer. java so that it only echoes every other dat agram it receives. Verify
  that UDPEchoClientTimeout. java ret ransmi t s dat agrams until it either receives a reply or
  exceeds the number of retries.
  8. Modify UDPEchoServer. java so that ECHOMAX is much shorter (say, 5 bytes). Then use
  UDPEchoClientTimeout. java to send an echo string that is too long. What happens?
  9. Verify experimentally the size of the largest message you can send and receive using a
  DatagramPacket.
  10. While UDPEchoServer. java explicitly specifies its local port in the constructor, we do not
  specify the local port in UDPEchoClientTimeout. java. How is the UDP echo client's socket
  given a port number? Hint: The answer is different for TCP.
  chapt er 3
  Sending and Receiving Messages
  When writing programs to communicate via sockets, you will generally be implementing
  an application protocol of some sort. Typically you use sockets because your program needs to
  provide information to, or use information provided by, another program. There is no magic:
  sender and receiver must agree on how this information will be encoded, who sends what
  information when, and how the communi cat i on will be terminated. In our echo example,