Documente Academic
Documente Profesional
Documente Cultură
Network
Applications
In distributed programming, programmers distribute the task across the network. A popular way to
distribute work over a network is through RPC, that is, Remote Procedure call. Client – server
applications that use a network server for important services, such as database etc. are one popular
interpretation. We can broaden distributed computing further to indicate agents and peer – to – peer
services. The important feature of distributed computing is that it involves two or more computers
communicating with each other.
The main characteristic of network program is that they must use a computer network in anyway as
to perform their job.
Network Programs do either of one or all of the following –
Send data across the network.
Provide services over a network.
Receives data over a network.
Invoke services across a network.
Network programming includes –
Reading and writing network sockets
Encryption and decryption of data
Translating network protocols
Sending data packets to other nodes
Providing security to the data
And many more. . .
Terms used in Network Programming
In the network programming two terms are used frequently – Client and Server.
Client
A client is a network program residing on local host who requests for any service to the server. A
client it is started by the user and terminates when the service is complete. For example Web
browser is a network client – which requests to the Web Server to read files, view images or
download documents or images on the local PC.
Server
A server is a network program residing on the remote computer which provides services to the
Network Client on request. A server program is an infinite process. When it starts it runs infinitely,
unless a problem arises, and waits for the requests from the client. For example, Web Server is
network server – which runs infinitely and waits for the requests made by clients. When client made
request for any service to server, it interprets it and perform or provide services.
Protocol
A protocol is an agreed – upon way of exchanging information and service requests between client
and servers. FTP, for example, is a frequently used protocol for transforming files on the Internet.
Other operations are also possible with FTP, such as creating directories, deleting files, and so on.
What Network Programs can do?
Networking extends the power of a single computer. Network lets one computer communicate with
thousands, even millions, of other computers.
Information sharing
Network programs are principally used to share information. At their simplest form, network
programs either send or receive data through networking channels. For example, if a company has
five offices, say at Kolkata, Chennai, New Delhi, Mumbai and Banglore, then the proprietary
software may be kept at one location say at the center New Delhi. Now the distant users at other
centers, Kolkata, Mumbai, Chennai and Banglore, can use the same software, thus reducing the cost
of multiple purchase of the same software.
Parallel Computing
In parallel computing, different components work on the parts of the same single problem. And after
the completion of the particular problem they were handling return the result back. Parallel
computing extends the idea of multi tasking and multithreading.
Distributed Computing
Parallel computing does not divides its work to a single physical server rather it can distribute the
task among different servers, which is called distributed networking. In distributed networking an
application Program can be divided into different distinct parts or modules. These modules can be
executed from different servers to extend the processing capabilities of the system.
Application Services
Java is an excellent tool for implementing custom networking applications defining clients, servers
because it has multiple technologies for sending and receiving data over a network. Java network
applications can use technologies that are 100% Java and can also use non – Java technologies. Java
applications can use network connections to pass data and request services.
Web Services
Java is widely used to implement e–commerce applications. In fact, the popularity of Java is mostly
due to this reason that it provides the easy ways to develop an e – commerce applications. Applets
can provide and enhanced user interface right inside a web browser window. Servlets provide an
additional power to the web servers.
Application areas of Network Programming
Network may prove very efficient in the area of –
Electronic mail
Application Services
Information sharing
Parallel computing
Messaging services
Website programming
And many more . . .
Network Programming & Java
The available network programming features in the earliest release of Java included only low – level
programming. It was possible to create sophisticated Internet applications with Java 1.0, but a Java
network programmer had to know how to do it with basic level network programming such as socket
programming.
As java has matured so has its network programming features. New API’s & new tools were added
to shield programmers from low – level network programming. These new APIs and tools use low –
level network programming “under the hood”. They provide developers with some important
benefits –
Productivity – The new APIs and tools make developers more productive so network
applications can be written quicker and with less code.
Maintainability – The new APIs provide high – level object models and functions libraries.
A single method can replace dozen of times of low – level networking programming,
making source code more readable.
Robustness – Low – level network programming is error – prone. It can be complicated,
with many possibilities for subtle srrors therefore, through testing and considerable
debugging are usually required. The new APIs and tools undergo thorough testing and
debugging allowing the developer to leverage that effort. Network applications become less
fragile.
The foundation for Java networking is located in the java.net and java.io packages. The java.net
package provides the classes for implementing network applications. These classes are used to build
applications that rely upon TCP/IP and UDP. The java.io package provides classes for system input
and output through data stream serialization and the file system. Servlets and JSP allowed Java
developers to build sophisticated web applications.
The various java.rmi packages are used to develop RMI applications, a mechanism that enables an
object on one Java virtual machine to invoke methods on an object in another Java virtual machine.
Java network programming also uses other classes depending upon the application –
The java.Security programming package provides the interface and classes for Java’s
security frame work.
The various org.omg.CORBA packages add CORBA support to Java.
The javax.rmi packages provide the APIs for RMI – IIOP.
A server is a remote computer on a network which provides services to the clients. When it starts, it
opens the channel for incoming requests from clients, but it never initiates a service until it is
requested to do so.
A server program is an infinite program. When it is starts in runs infinitely unless a problem arises.
It waits for incoming requests from clients. When a request arrives, it responds to the request either
iteratively or concurrently.
Most of the client-server programming centers on two broad categories of applications-
Custom Business Applications- These types of software are created by IT consultants.
These are specially designed software’s which runs on LAN.
Internet Applications- These applications are designed to run on World Wide Web. Client-
server computing is largely used to develop e-commerce and business to business
applications which run on World Wide Web.
Characteristics of Client-Server Model
Services- Servers respond to service requests from clients.
Separate Processes- Servers and clients run in their own distinct processes. Those processes
do not need to run on separate machines to qualify as client-server. Client and server could
instead operate in their own addresses spaces on the same machine.
Asymmetrical Relationship- Clients and servers are not peers they cannot swap the roles.
Clients initiate communication by requesting a service. Servers fulfill those requests.
Between service requests, servers passively wait for clients to request a service.
Loose Coupling- Servers encapsulates their functionality. A client can initiate a service in
several ways such as making a remote procedure call or passing a message to the server.
Implementation details for service are unknown by client.
Location Transparency- The server process can run on the client machine or it can run on a
remote machine.
Scalability- This is done in two ways- distributing the process load across more processors
or through techniques like multithreading. The client-server system can be scaled by
distributing the processing across multiple machines- "distributed computing ". Clustering
is a form of distributed processing that uses multiple machines to work together as a single
system, sharing the same namespace. This improves both the scaling and reliability. If a
machine in a cluster crashes, other servers can redistribute the load. The load is balanced
across the machines in the cluster to provide the maximum performance.
Applications of the Client-Server Model
Client-server is a useful model for sharing and managing resources on a network. Some common
examples of client-server model applications are-
File Servers – The network file server manages the network. It acts as a shared
repository for different information files such as, documents, image files, etc.
Database Servers – In the network client passes SQL requests to database servers. The
database server than perform the queries and returns the result back to the client.
Proxy Server – Proxy servers are used to manage Internet connections for an
organization. They are often implemented as part of a security firewall denying those
behind it access to the Internet and more importantly access from the Internet to an
internal network.
Email Servers – Email servers provide 24–7 reliability. Client workstations can fetch
their email by making calls to the email server with the POP3 and other email protocols.
Application Servers – Application servers provide business logic services, often through
components, such as Enterprise Java Beans (EJB). Application servers frequently offer
additional features, such as transaction management and load balancing.
Print Servers – Print Servers allow multiple workstations to access shared printer. Print
Server also allow for remote administration of servers, such as cancellation of print jobs.
Client-Server Mechanism
A client initiates a request of some sort and the server provides an appropriate response. The same
process can be a client or a server; it can even be both at the same time. For example, client A can
invoke a method on server B. Server B can then invoke a method on another server, server C. Which
role a process plays, client or server, depends upon the relationship between the two processes for a
particular context. Change the context and their respective roles can change.
1 1
2 2
1. REQUEST: Client initiates a connection, made request for the service to server.
2. RESPONSE: Server accepts the request, respond to the client and provide the services to
clients.
Sockets
Java programs communicate through a programming abstraction called socket. A socket is one end-
point of a two-way communication link between two computers (or programs) running on a network.
A socket is bound to a port number so that the TCP layer can identify the application that data is
destined to be sent.
P P
O O
R R
T T
Ports
One mechanism that is commonly used by network protocols, and in particular the Internet transport
layer protocols, is port addressing. Every network service is associated with one or more ports on
one or more IP interfaces of its host device. Typically, integer numbers are used to identify different
ports. In order to contact a network service, it is therefore necessary to provide both the IP address of
its host, as well as port number it is using.
Client-Server: The Architecture
One of the most difficult things about developing client-server applications is deciding how to split
the work between client process and server process.
Single – Tier Architecture
User Interface
Processing
Reading/Writing
Data
Figure: Single – Tier Architecture
Submit Input
Display Output
The approach of these applications is centralized in which multiple users are allowed to work
simultaneously. Clients provide only user interface and rest of all the processes are run on server
side. All the services and data access provided by server is shared by all the users working on the
application.
Three – Tier Architecture
User-Interface Tier – This tier handles the user interface logic. This is normally on the
client side.
Business Rule Tier – This tier handles all of the business rules logic and validates user
input from user interface tier.
Data-Store Tier – This tier is concerned with the storage and retrieval of data from
databases.
Advantages of 3-Tier Architecture
Moving business rule components to an application server can boost performance.
Multiple application servers can take advantage of load balancing and improve system fault
tolerance.
Changes to business rule can migrate to a small number of application servers instead of a
large number of workstations.
This also provides better code encapsulation allowing different people or even companies to
implement each tier.
Multi – Tier Architecture
Multi-tier or n-tier architecture takes the partitioning of application services even further. They
divide the business rule services tier into collaborating tiers – one for business rule processing that
supports the user interface and the other for business rule processing that integrates and manipulates
data.
UI
Oriented
Business
Rule
INTERNET ADDRESSING
Internet
The Internet is a network of networks, all of which agree to communicate using a standard set of
protocols. Several Inter-networking technologies were developed in the 1970’s and 1980’s. One of
these was the collection of protocols standard by the Internet Engineering Task Force (IETF).
The Internet Protocol (IP) is the core of this protocol suite. The basic communication model of the
IP is that of a connection-less, best-effort packet service. Internet nodes wishing to send data across
the network to a destination node must first breakdown data into smaller data-segments called
packets. Each packet is then transmitted individually on a hop-by-hop basis towards the destination
node. Internet nodes performing forwarding functions are called routers. Packets are forwarded with
best effort so they may not be lost, get corrupted or arrive out of order at the destination.
The three basic functions of Internet communications are addressing, naming and routing.
Addressing – An Internet address uniquely identifies the location of an Internet node. In a
sense, an Internet address is like a traditional mailing address. If a node moves to a different
network, its address will change. Moves within same network may, or may not require a
change in address. This is similar to moving within a building with un-numbered apartments,
versus moving within a neighborhood.
Naming – Names provide a location-independent reference to Internet nodes. Unlike Internet
address that is essentially large integer numbers; names may contain letters and certain
symbols making them easier for human to remember. In order to communicate with an
Internet node identified by a name, an application must lookup (resolve) the Internet address
for that name. The operation is similar to using a phone book to lookup the number of a
person by using his or her name. Unlike printed phone books, the Internet name directory can
be changed as often as needed, therefore when a node moves; its name-to-address listing may
be updated immediately. Although the IP does not mandate any particular mechanism or
protocol for name-to-address resolution, the Domain Name System (DNS) has become the
de-facto Internet Naming Mechanism.
Routing – Internet nodes forwards their destination address using local routing information.
Internet nodes used to forward packets between destination are called routers. Routers may
be statically configured, or may compute their forwarding table dynamically using one of
several dynamic routing protocols. The advantage of computing rotes dynamically is that the
network can recover from failures by redirecting traffic over alternative paths. Internet
routing decisions are hidden from users and can only be modified with administrative
privileges,
java.net.INETADDRESS
Java encapsulates the concept of IP address in a class, which is part of the java.net package and is
called InetAddress. This class allows to manipulate a 32-bit IP address in a more high level fashion
than by just using a single 32-bit integer. Class InetAddress essentially lets one to convert a textual
Internet address of the form host.subdomain.domain into an object representing that address.
InetAddress class contains following methods –
getByName() : java.net.InetAddress
getAllByName() : java.net.InetAddress
getLocalHost() : java.net.InetAddress
getHostName() : String
getAddress() : byte[]
getHostAddress() : String
isMulticastAddress() : Boolean
getByName()
The most commonly used method is getByName() with the following signature –
static InetAddress getByName(String host) throws UnknownHostException
This method returns an InetAddress object encapsulating the result of a DNS lookup on the string
domain argument. For example, invoking getByName (“myweb.com”) will return an InetAddress
instance storing the domain name “myweb.com” as well as the resolved address
("204.148.170.161”).
If the string method argument represents an IP address in dotted decimal notation then the object
created will encapsulate the given address. For example, invoking getByName(“204.148.170.161”)
will create an InetAddress.
If the domain name can not be resolved the java.net.UnknownHostException is thrown. The
method may also throw a runtime SecurityException, in case if a Java Security Manger has been
installed, and the code-base has not been given the resolve permission.
getAllByName()
The second method is similar to the previous method with the difference that all lookup results are
returned. This method may also throw a runtime SecurityException if a security manager has been
installed and the resolve permission has not been granted.
static InetAddress[] getAllByName(String host) throw UnknownHostException
getLocalHost()
The third and final method does not take any argument and returns an InetAddress object
representing the IP address and name of the host executing the JVM. Most modern operating
systems support a look-back network interface that is usually assigned the special IPAddress
127.0.0.1 and is commonly mapped to the name “localHost”.
This method may throw the UnknownHostException. In this case this exception is used to signal an
error in obtaining a local IP address.
Read Methods
The InetAddress class provides four read methods for querying the state of instances. The methods
do not throw any exceptions since all possible exceptions would have been thrown by previous
methods.
String getHostName() – Returns the domain name of this address, for example, yahoo.com.
byte[] getAddress() – Returns the address 32-bit value as a 4 byte array in network byte-
order, for example,
new byte[] {(byte) 0xCC, (byte) 0x94, (byte) 0xAA, (byte) 0xA1}
String getHostAddress() – Returns the dotted decimal string representation of this address,
for example, 204.148.170.161.
boolean IsMulticastAddress() – Returns true if this is a multicast address.
In addition to the above four methods, the InetAddress class overrides the following default
java.lang.Object methods –
int hashCode() – Returns an integer (32-bit) value representing the IP address.
boolean equals() – returns true if he argument is an InetAddress instance encapsulating the
same IP address.
String toString() – Returns a string representation of this address. The current implement
returns a string containing both the dotted decimal IP address representation and the host
name.
Example code displaying usage of getByName() and getAllByName() –
//InetAddExample.java
import java.net.*;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class InetAddExample{
public static void main(String[] args) throws UnknownHostException{
InetAddress address = InetAddress.getByName(“starware.com”);
System.out.println(address);
InetAddress sw[] = InetAddress.getAllByName(www.yahoo.com);
for(int i=0;i<sw.length;i++){
System.out.println(sw[i]);
}
}
}
Stream Segmentation – TCP breaks the stream into segments, because the IP protocol only
supports transmission of limited size packets. It is preferable to transmit packets containing
the largest possible payload to reduce the cost of transmitting the IP and TCP headers.
Stream Reassembly – Sometimes the TCP streams that are transmitted as IP packets may
arrive at the destination in different order than the order sent. TCP must be able to handle
out-of-order delivery and still reassemble the data in the order transmitted. TCP addresses
this problem by counting the number of bytes transmitted in the stream and identifying each
of the first stream byte it carries.
Handling Packet-loss - IP packets carrying segments of the stream may be lost in the way.
TCP must be able to detect that a packet has been lost and arrange retransmission.
TCP deletes packets loss by positive receiver acknowledgements. When a TCP packet
arrives, the receiver’s TCP protocol implementation will send a TCP packet to the sender
acknowledging receipt. If the sender fails to receive acknowledgement by a certain deadline,
it will retransmit the packet.
Data Corruption Detection - The IP protocol only protects its own header and does not
make any guarantees on the payload contents. It is therefore possible that one or more bits in
the payload may be corrupted due to transmission error.
For this payload’s summary is computed and stored in the packet’s header. The receiver of
the packet then independently computes the summary of the data received, using the same
algorithm and compares it to summary stored in header. This algorithm protects against all 1-
bit errors and some multiple bit errors.
Throughput Efficiency – The design of a reliable streaming channel is further complicated
by the requirement for efficiency. For this one could develop a stop and wait design in
which the sender transmits the next packet of data in which the sender transmits the next
packet of data every, certain-milliseconds until an acknowledgement is received. But in this
design the maximum throughput is limited by the communication round-trip overhead.
TCP addresses this problem by using a technique called sliding-window. In this approach,
the receiver instructs the sender on the maximum number of unacknowledged bytes that can
be transmitted (the window). Once the sender has transmitted a window-size full of data, he
must wait for a receiver acknowledgement. When it has been received, the sender can send
out as much data as was acknowledged. This mechanism increases the concurrency of
operation as well as enables receivers to the control the flow of transmission.
Java TCP Programming
The programming model of TCP communication in Java, rely completely on the sockets and ports.
Because TCP is a stream protocol, it allows to send arbitrary amount of data rather rely on class to
encapsulate data within TCP packets.
Sockets
Java programs communicate through a programming abstraction called socket. A socket is one end-
point of a two-way communication link between two computers (or programs) running on a network.
A socket is bound to a port number so that the TCP layer can identify the application that data is
destined to be sent.
Mostly, applications do not care how data is actually transmitted in the network. Applications
identify the address of the peer entity and then use sockets interface to read and write data from and
to the peer. Sockets include the implementation of network and transport layer protocols providing
applications with a simple read/write interface.
Because sockets are just programming abstractions for network protocols, the other side of the
connection does not have to use them. Sockets don’t use any additional communication mechanism
other than that provided by the encapsulated protocol.
The socket abstraction was developed in the first networked version of UNIX developed at the
University of California at Berkeley by Bill Joy. Those sockets are therefore, also known as
Berkeley sockets. Traditionally, sockets abstraction as a core language library feature in order to
support portable, cross-platform network programming.
Ports
One mechanism that is commonly used by network protocols, and in particular the Internet transport
layer protocols, is port addressing. Every network service is associated with one or more ports on
one or more IP interfaces of its host device. Typically, integer numbers are used to identify different
ports. In order to contact a network service, it is therefore necessary to provide both the IP address of
its host, as well as port number it is using.
Each published protocols are assigned with certain port number, what are called “well-known port
numbers”. The advantage of this solution is that an additional port-directory mechanism is not
needed. Every standard Internet application requests a port number from the Internet Assigned
Numbers Authority (IANA). For example, tcp:23 port number is assigned for FTP, tcp:80 for
HTTP, etc.
IANA reserves ports 1 – 1023 for well-known services. Less popular or platform-specific services
can still request registration of ports in the range of 1024 – 49151. If a service is meant for Internet
deployment, then users can just pick up a port number that is not already assigned. Both the client
and server must then be configured to connect to and bind to the given port. Finally, ports in the
range 4915 – 65535 are typically used for port assignment.
Stream Sockets
TCP
TCP
ServerSocket
The diagram illustrates the use of sockets to establish two-way byte-streaming communication. On
the left hand side of diagram is a Java-client program wishing to connect to the server on the right.
In order to receive remote connections, the server program must first create a ServerSocket. A
server is a receiver of incoming connection requests. Each protocol has its own server socket type.
For a TCP communication following steps are involved –
The server program creates a TCP server socket bound to port 4567.
At this point the server invokes the accept() method on the server socket and blocks waiting
for the first client connection.
Java client program creates a regular socket with the same name or address of the server host
as well as the port number of the server program. This protocol type of client socket must
match the protocol type of the server.
Upon creation, the socket object attempts to establish communication with its peer using the
TCP protocol.
Once the TCP handshake is complete, the server socket creates a socket to model the server’s
side of the TCP communication.
This is returned as the result of the blocked accept() call.
At this point, the client and the server are each in possession of a socket object and in bi-directional
link. Now in order to transmit information, both the client and the server must obtain an input and
output stream from the socket object (steps 8 and 9).
Package java.net
The Java language supports TCP programming through the java.net.Socket and
java.net.ServerSocket classes. Java clients connect to TCP servers by creating instances of the
java.net.Socket class. Similarly, Java servers listen for java clients by creating
java.net.ServerSocket class. Connections are configured through the methods of these two classes.
Actual network communications, however, are performed using the java.io package streaming
classes.
The diagram below illustrates the main operations of the Java streaming socket classes. The Java
TCP server, on the right, accepts TCP connections by creating a java.net.ServerSocket instance
bound to a particular port. When a ServerSocket establishes a connection with a TCP client, it creates
a java.net.Socket instance encapsulating that connection and returns it to the server program. The
java.net.Socket object returned is bound to an ephermal port number that is different from the one
the ServerSocket is listening to. The server retrieves the socket’s input and output streams and
effects communication by implementing some protocol.
java.n
rSock
Serve
et
et
TCP create(port)
Connect accept() call
create return
(server, to
Java Java
Socke
Socke
java.n
java.n
port) accept()
et
et
Client t
t
TCP Server
create creates
Outpu
tStrea
java.i
java.i
Input
Strea
m
m
o
Outpu
tStrea
java.i
java.i
Input
Strea
m
m
o
o
Figure: Main Operations of Java Streaming Classes
On the client side, TCP connections are established through instances of java.net.Socket associated
with a TCP server on the given host and port. Once the client Socket has established a TCP
connection, retrieves the socket’s input and output stream, effects communication.
Client-Side TCP Programming
The java.net.Socket of a java.net package implements client side of a two-way connection between
Java program and another program on the network. By using this class instead of relying on native
code, Java program can communicate over network in platform independent fashion.
Creating a Socket
In order to establish a connection with a network server one must have the address of the server’s
host, and port number to which the server is bound. The java.net.Socket class provides a
constructor, which takes an IP address and port number and attempts to establish a connection. The
signature of this constructor is as follows –
Socket(InetAddress, int port) throws IOException;
The constructor returns only after the connection has been established, that is, once the TCP three-
way handshake has been completed. Hence the constructor must signal errors in establishing the
connection. Throwing the java.io.IOException exception signals such communication error.
A connection attempt may fail for multiple reasons. For example, either the remote IP address may
not reachable or IP address may be reachable but server may not be bound to the specific port
number on the given address. Although the signature of the constructors only declares the
java.net.IOException, users wishing to programmatically determine the reason for the connection
failure, can try to catch the following java.io.IOException subclasses –
java.net.NoRouteToHostException – This indicate that the client or server host is not
connected to the network, or that there is no path from the client’s network to the server’s
network due to some failure.
Java.net.ConnectException – The network of the remote server can be reached, but either
no host has been assigned the specified address, or a host is reachable but no application is
listening to the specified port on this protocol used.
Additionally, the constructor may throw the runtime exception java.lang.SecurityException if a
security manager has been installed, and the connect action has not been provided for the target IP
address and port.
A similar constructor is provided for use with host names, or IP addresses represented as Strings.
The signature is as –
Socket(String host,int port) throws IOException;
This constructor may also throw an additional IOException subclass called
java.net.UnknownHostException if the host name can not be resolved, or string representation of
the IP address is invalid. There is another equivalent constructor with the previous constructor,
which is much more convenient –
new Socket(InetAddress.getByName(host),port);
Example of a simple program demonstrating Socket Creation –
//SimpleClient.java
import java.net.*;
import java.io.*;
public class SimpleClient{
public static void main(String[] args){
String host = “sap_server”;
Int port = 1234;
try {
System.out.ptintln(“Attemting to connect to a TCP service on host “
+ host + “and port: “ + port);
Socket s = new Socket(host,port);
System.out.ptintln(“Connection Esteblished . . .“);
}catch(UnknownHostException ue){
System.out.ptintln(“Trouble: “ + ue.getMessage());
}catch(IOException ioe){
System.out.ptintln(“Trouble: “ + ioe.getMessage());
}catch(SecurityException se){
System.out.ptintln(“Trouble: “ + se.getMessage());
}
}
}
Once the input and output streams for the socket have been obtained, it is up to application to
determine the contents of communication.
Getting Socket Information
Connection oriented sockets encapsulate a connection to a network peer or remote host, therefore,
they may be characterized by set:
<local_address, local_port, remote_address, remote_port>
The four methods for querying the Socket local and remote addresses and port numbers are –
InetAddress getInetAddress() throws IOException;
int getPort() throws IOException;
InetAddress getLocalAddress() throws IOException;
int getLocalPort() throws IOException;
Terminating socket
As file objects also consume finite operating system resources. An open socket keeps a local port
busy, and in most cases uses at least one native operating system file handle. Both port numbers as
well as file handlers are limited and therefore it is very important to explicitly close sockets when the
connection is no longer needed. The close(0 method requests asynchronous termination of the socket
connection.
The close() method will return immediately, even if data written before invocation has not
completed transmission. The default semantics of the method invocation are that delivery of data
written before invocation will continue to be attempted until successfully delivered. It is possible to
limit the maximum duration of pending data delivery using the setSoLinger() method.
void close() throws IOException;
Once a socket has been closed the input and output stream may no longer be used. An attempt to
read and write data from input stream and to output stream will result in IOException. An attempt to
read and write data from input stream and to output stream will result in IOException. An
alternative way to close a socket is to invoke a close(0 method on either the input or only the output
directions of the connection. The two methods for effecting such behavior are –
void shutdown Input() throws IOException;
void shutdown Output() throws IOException;
Example code illustrating reading/writing through Socket
The example program implements a client, EchoClient, that connects to the EchoServer. The
EchoServer simply receives data from client and echoes it back.
EchoClient creates a socket thereby getting a connection to the Echoserver. It reads the input from
the user on the standard input stream, and then forwards that to the EchoServer by writing the text to
the socket. The server echoes the input back through the socket to the client. The client program
reads and displays the data passed back to it from the server.
//EchoClient.java
import java.net.*;
import java.io.*;
public class EchoClient {
public static void main(String[] args) {
Socket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try{
echoSocket = new Socket(“sap_server”,7);
out = new PrintWrite(echoSocket.getOutputStream(),true);
in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream());
}catch(UnknownHostException ue) {
System.out.ptintln(“Trouble: “ + ue.getMessage());
}catch(IOException ioe){
System.out.ptintln(“Trouble: “ + ioe.getMessage());
}catch(SecurityException se) {
System.out.ptintln(“Trouble: “ + se.getMessage());
}
BufferedReader stdIn = new BufferedReader(new InputStreamReader(system.in));
String userInput;
while(!(userInput = stdIn.readLine()).equals(“quit”)) {
out.println(userInput);
System.out.println(“Echo: “ + in.readLine(0);
}
out.close();
in.close();
stdIn.close();
echoSocket.close();
}
}
EchoClient both writes to and reads from its socket, thereby sending data to and receiving data from
the EchoServer.
The three statements in the try block of the main method are critical. These lines establish the socket
connection between the client and the server and open a PrintWriter and a BufferedReader on the
socket.
echoSocket = new Socket(“sap_server”,7);
out = new PrintWrite(echoSocket.getOutputStream(),true);
in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream());
The first statement in this sequences creates a new Socket object and names it echoSocket. The
Socket constructor used here requires the name of the machine and the port number to connect, the
example program uses the host name “sap_server”. This is the name of a hypothetical machine on
local network. The second argument is the port number. Port number 7 is the port on which the
EchoServer listens.
The second statement gets the socket’s output stream and opens a PrintWriter on it. Similarly, the
third statement gets the socket’s input stream and opens a BufferedReader on it.
The example uses readers and writers so that it can write Unicode characters over socket.
To send data through the socket to the server, EchoClient simply needs to write to the PrintWriter.
To get the server’s response, EchoClient reads from the BufferedReader.
The next part of the program is the while loop. The loop reads a line at a time from the standard
input stream and immediately sends it to the server by writing it to the PrintWriter connected to the
socket.
String userInput;
while(!(userInput = stdIn.readLine()).equals(“quit”)) {
out.println(userInput);
System.out.println(“Echo: “ + in.readLine(0);
}
The last statement in the while loop reads a line of information from the BufferedReader connected
to the socket. The readLine method waits until the server echoes the information back to the
EchoClient. When readLine returns, EchoClient prints the information to the standard output.
The while loop, continues until the user types an end-of-input character. That is, EchoClient reads
input from the user, sends it to the EchoServer, gets a response from the server, and displays it, until
it reaches the end-of-input. The while loop then terminates and the program continues, executing the
nest four lines of code –
out.close();
in.close();
stdIn.close();
echoSocket.close();
These lines of code fall into the category of housekeeping. A well behaved program shoul always
cleans up after itself. These statements close the readers and writers connected to the socket and to
the standard input stream, and close the socket connection to the server. The order here is important
because any streams connected to the server should be close before the socket.
Server-side TCP Programming
In order to accept network connections a Java program must create an instance of
java.net.ServerSocket. Server sockets are not directly used to perform any network communication.
Instead, they act as factories that create a java.net.Socket object for every incoming TCP
communication request. Programs create the server socket, bind to a specific port on one or more
interfaces, and then invoke the blocking accept() method.
Creating ServerSocket
The basic ServerSocket constructor takes a single argument, the TCP port number used in binding. If
the constructor returns without throwing an exception then the server socket has successfully bound
to the requested TCP port. The constructor may fail due to an I/O error, or due to a security error.
The signature of the constructor is –
ServerSocket(int port) throws IOException,SecurityException;
Port is not permitted to listen more than one process at the same point of time. Therefore, if any
process has created a socket bound to the specified port an IOException will be thrown.
An additional constructor is also provided, which permits users to specify the size of the connection
backlog queue. Because the client connection requests happen asynchronously, it is possible that
new requests will be received before the server program has been able to invoke the accept()
method. In such cases, the requests are placed in a queue, and retrieved on subsequent accept()
invocations. This constructor throws the same exceptions as the basic constructor, that is,
IOException and SecurityException. The signature of this constructor is as follows –
ServerSocket(int port, int backlog) throws IOException, SecurityException
The third and final constructor permits user to bind to a particular local interface. Port numbers are
assigned per protocol per interface. The previous two constructors attempt to bind program to the
specified port on all available interfaces. The signature of this constructor is –
Server Socket (int port, int backlog, Inet Address bind Address)
throws IO Exception, Security Exception
Accepting Sockets
The main task of server socket is to receive incoming connection requests and generate a
java.net.Socket object that encapsulates each request. Incoming connections are queued until the
program retrieves them one at a time by invoking the accept() method. The accept() method takes no
arguments, and returns the next connection in the queue.
If no connection requests are pending then the method blocks until a request is made, or the
optionally specified connection timeout has expired. The method may throw an IO Exception if the
Server Socket has been closed, or a communications error is encountered. The method may also
throw Security Exception if the incoming connection originated from a host/port not covered by an
accept socket permission.
//SimpleServer.java
import java.net.*;
import java.io.*;
public class SimpleServer{
public static void main(String args[]){
ServerSocket server = null;
int port = 1234;
try{
System.out.println(“Attempting to bind a TCP port “ + port);
server = new ServerSocket(port);
}catch(SecurityException se){
System.out.println(“Trouble : ” + se.getMessage());
}catch(IOException ioe) {
System.out.println(“Trouble : ” + ioe.getMessage());
}
try{
Socket socket = server.accept();
System.out.println(“Accepting connection from: “ +
Socket.getInetAddress.getHostName());
socket.close();
}catch(SecurityException se){
System.out.println(“Trouble : ” + se.getMessage());
}catch(IOException ioe){
System.out.println(“Trouble : ” + ioe.getMessage());
}
}
}
Echo Server listens to its client Echo Client. It receives data being Echo Client and send it back to
the client as it is.
The server program begins by creating a new Server Socket object to listen on a specific port. The
port number used in this case is 4444.
try{
serverSocket = new ServerSocket(port);
}catch(SecurityException se){
System.out.println(“Trouble : ” + se.getMessage());
}catch(IOException ioe){
System.out.println(“Trouble : ” + ioe.getMessage());
}
Server Socket is a java.net.class that provides a system independent implementation of the server
side of a client – server socket connection. The constructor of Server Socket throws an exception if it
can’t listen on the specified port. (for example, the port is already being used. In this case, the Echo
Server has to exit.
If the server successfully connects to its port, then the Server Socket object is successfully created
and the server continues to the next step – accepting a connection from a client.
try{
clientSocket = serverSocket.accept();
} catch(SecurityException se){
System.out.println(“Trouble : ” + se.getMessage());
} catch(IOException ioe){
System.out.println(“Trouble : ” + ioe.getMessage());
}
The accept() method waits until a client starts up and requests a connection on the host and port of
server. When a connection is requested and successfully established, the accept method returns a
new socket object which is bound to a new port. The server can communicate with the client over
this new socket and continue to listen for client connection requests on the Server Socket bound to
the original, predetermined port.
After the server successfully establishes a connection with a client, it communicates with the client
using this code:
PrintWriter out = new Print Writer (client Socket.get out put stream() );
BufferedReader in = new BufferedReader(new InputstreamReader(clientSocket.getInputStream());
The first statement here gets the client socket’s output stream and opens Print Writer on it. Similarly
in the next statement gets the client Socket’s input stream and opens a Buffered Reader on it.
String inputLine;
boolean finished = true;
do {
inputLine = in.ReadLine();
if(inputLine.equalsIgnoreCase(“quit”))
finished = true;
out.println(“Received : “ + inputLine());
out.flush();
}while(!finished);
To send data through the socket to the client Echo Server simply needs to write to the Print Writer.
To get the client’s response, Echo Server reads from the Buffered reader.
The next intensity part is do - while loop. The actual communication starts from this loop. The loop
reads a line at a time from the Input stream and immediately sends it to the client by writing it to the
Print Writer.
The do - while loop continues until the client sends “quit” to it. The do – while loop terminates and
the program continues to execute next lines of code:
in.close ();
out.close ();
client.Socket.close ();
server Socket.close ();
first two statement close the readers and writers connected to the socket. Next two statements close
the socket connections of client and server.
UDP is very thin layer on top of IP, providing three additional functions –
Destination Port Addressing – UDP datagram are marked with a destination port address,
this is in addition to the destination IP address. When a UDP/IP datagram is delivered to its
destination address, the protocol stack consults the UDP destination port value to decide
application should receive this datagram. UDP port numbers are 16 – bit port integer values
in range of 0 – 65535.
Although both the UDP and TCP protocols empty ports in the same range as a common de –
multiplexing mechanism, their actual use is independent of one another. It is perfectly
permissible for the same port number to be used by a TCP application and a UDP
application, or by other protocol for that matter. This is possible because the IP protocol
performs an initial de – multiplexing based on protocol type, so UDP and TCP packets are
separately identified and treated.
Data Payload Integrity Verification – UDP associates a 16 – bit checksum with each
datagram sent. A checksum is a summary of the datagram contents computed using an
algorithm agreed upon between the sender and the receiver. Before transmitting the UDP
datagram, the sender computes this checksum summary and stores it in the UDP header.
Upon delivery, the recipient also independently computes the checksum for the datagram and
then compares it to the checksum stored in the UDP header. If they are the same, the
datagram integrity is considered verified.
Because a checksum is only a summary, different messages may have the same checksum
value. The trick is to select a checksum computation algorithm that catches the most likely
errors. UDP employs an algorithm called One’s complement that catches all single bit –
errors and many multiple – bit errors (odd – number errors are more likely to be detected). In
principle, it is possible that a datagram may be corrupted in a manner that does not affect its
checksum, but this is extremely unlikely in practice because datagrams are rarely corrupted
and when they are, they are typically 1 – bit errors.
Source Port Identification – UDP stores the port number of the datagram socket used to
transmit a datagram. In combination with the IP header’s source IP address, they provide a
return address for UDP datagram receivers. IP and UDP are connections less protocols and
therefore when a datagram is delivered there is no backward channel to send response to. The
solution is to store the sender’s address and port in each UDP datagram to provide a unique
return address.
IP Fragmentation
A UDP datagram consists of the IP header (minimum 20 – bytes maximum 60 – bytes), and a fixed
length UDP header (8 bytes), followed by the payload data.
Both IP and UDP headers maintain packet length as a 16-bit value, therefore the largest UDP data
payload can be (216 –20 – 8) = 65508 bytes. However, most link layer protocols do not support such
large packet sizes. Link protocols typically have their own Maximum Transfer Unit (MTU). The
MTU specifies the largest frame (link-layer packet) that can be transmitted over a specified link
technology; for example, Ethernet frames can carry up to 1500 bytes of data. When an IP router
needs to transmit an IP packet that exceeds the MTU of the next-hop link; it may either drop the
packet, or perform IP fragmentation. In IP fragmentation, a single IP datagram is broken into
multiple, smaller IP datagrams that are re-assembled at the destination.
After the fragmentation all fragments are delivered using different possible routes. The fragmented
packets will be reassembled at the destination. As separate IP packets, fragments may arrive at the
destination out of order, and some may even be lost. If any fragment is lost, then the destination will
be unable to reassemble the original IP datagram so will drop it.
TCP sockets, no differentiation exists between server and client UDP sockets. Every datagram
Socket can be used both for sending, as well as, receiving datagram packets. The reason for
difference is that stream sockets are associated with a single stream, while datagram sockets do not
support a streaming abstraction and can be used to send and receive to and from multiple
destinations. Datagram Packets can be broadcast to multiple recipients all, listening to a Multicast
Socket.
In place of the java.io stream classes, Java datagram sockets use instances of the Datagram Packet
class. Datagram Packet instances are used to standard mail envelopes, containing a destination or
source address as well as a message of certain maximum size. Datagram Packet instances may only
be used with Datagram Socket instances, and cannot be used with TCP java.net.Socket instances.
The diagram illustrates the typical use of the Datagram Socket and Datagram Packet classes –
[2] Create
DatagramPacket
[5] Create
Java Java (buffer)
DatagramPacket
Client (“server”,4567,data) Server
Program Program
java.net java.net
Datagram [1] Create Datagram
Packet (4567) Packet
[4] Create
(any)
[6] send [3] receive
(datagram) (datagram)
UDP
Desti-
java.n
java.n
Datag
Datag
ocket
ocket
ramS
ramS
(sourc
et.
et.
nation
data e
port) [8] write
port)
sender
Host/port
[7] Create UDP Header + data
send as IP packet
1. The java UDP server creates a Datagram Socket instance bound to a UDP port (specific
or arbitrarily chosen).
2. The server creates a Datagram Packet instance that will be used to store the next
datagram received.
3. The server than invokes the blocking Datagra Socket receive () method, passing the
datagram created.
4. The java UDP client creates a Datagram Socket instance, typically not bound to a
particular port.
5. The client next creates a Datagram Packet marked for delivery to the server’s address
and port, with the application – determined payload.
6. The datagram is then transmitted using the Datagram Socket’s send () method.
7. The header is created in transmission.
8. If the network manages to transmit the UDP packet to the other end (server) without
corrupting the headers or the payload, the data will be copied into the server’s Datagram
Packet instance and returned by unblocking the receive () call. If a receive () call has not
been made by the application the Datagram Packet instance will be buffered until it is
retrieved by the application. The checksum verification is performed by the system’s
UDP implementation and application can assume that delivered Datagram Packet
instances do not contain corrupted data.
java.net.DatagramPacket
The java.net.DatagramPacket class stores the header and data content of a UDP datagram.
Instances are used in sending as well as receiving UDP datagrams.
The three main attributes of the Datagram Packet class are –
IP address
UDP port
The payload data stored in a byte – array.
When Datagram Packet instances are used for UDP transmission, the IP address and ports specify
the destination. When used for receiving UDP datagrams, they specify the source IP address and
port.
Constructors
There are four ways to construct a DatagramPacket instance. The first two constructors are typically
used when reading UDP datagrams, the other two ways are typically used when transmitting UDP
datagrams. These uses are characterized as typical because the class provides update method
allowing programmers to supply missing arguments after construction. Construction can be defined
in following ways –
DatagramPacket (byte [] buf,int length)
This is the simplest constructor, which creates a DatagramPacket instance that uses the byte
array argument as buffer, and the integer argument as the maximum buffer length to be used.
An Illegal Argument Exception will be thrown if the buffer size of the array provided at
constructor execution time is smaller than the specified length.
The constructor, and in fact every DatagramPacket method, does not throw an I/O exception
since it does not perform any communication in itself. Communication only occurs through
java.net.DatagramSocket method invocations. If the application cannot predict the buffer size
it accepts to receive it should provide the maximum UDP size of 65508 bytes.
DatagramPacket (byte [] buff, int offset, int length)
This second constructor adds support for offsetting writes to the byte buffer. In the previous
constructor, the DatagramPacket created used data stored in buffer indices [0…..length – 1].
In this constructor, the instance created will use indices [offset……offset + length – 1]. This
behavior may be appropriate in applications that want to append the data received into an
array containing other data, or want to send part of the data stored in an array. An illegal
Argument Exception will be thrown if the buffer size is smaller than (offset + length).
DatagramPacket (byte [] buf, int length, Inet Address address, int port)
This constructor also accepts the byte array, length but also supports specification of the
packet’s destination address and port. The destination address and port are only used when
sending the packet using the java.net.DatagramPacket send () method. It is also possible to
use Datagram Packet instances to rreceive UDP datagrams in which case the address and port
values are overridden with the sender’s address and port. An Illegal Argument Exception
will be thrown if the buffer size is smaller than the specified length. No IO Exceptions are
thrown because the class does not perform any communications.
Datagram Packet (byte [] buf, offset, int length Inet Address address, int port)
This fourth constructor adds support for offsetting writes to the byte buffer to the third
constructor. In this constructor, the instance created will use indices [offset + length – 1].
This can be used to append the data received into an array containing other data.
Methods
The Datagram Packet class sup0ports read operations for accessing its three basic attributes
d: address, port, and data buffer (including buffer offset and length). No Exceptions are
thrown because the methods operate on local data.
Inet Address get Address () –
The get Address () method returns destination or source address for this packet.
Int get Port () –
The get Port () method returns the destination or source port number. It is up to the
application to remember if this packet has been constructed or received, in order to treat the
address and port number values accordingly. These methods get Address() and getPort() are
typically invoked on received datagrams in order to determine where the reply should be
sent.
Three methods are provided to access the Datagram Packet payload –
Byte[] getData ()
int getOffset ()
int getLength ()
The get Data () method returns the actual buffer, while the get offset () and get Length ()
methods return the range of buffer indices containing payload data.
The get Length () does not return the length specified in the constructor, but the actual length
of the data received of these methods, the get Length () is most commonly used to determine
how much data was received. If no offset has been specified, the get Offset () method returns
zero. In addition to the above read operations, DatagramPacket provides nearly equivalent
write methods.
Void set Address (Inet Address ) – This method may be used to change the destination of
the packet.
Void set Port (int Port ) – This method may be used to change the destination port of the
packet.
The Datagram Packet does not effect any communications, so setting the destination address
and port will only change behavior once the java.net.DatagramSocket send (Datagram Packet
method is invoked with the changed object as its argument.
It is possible to change the data buffer of the Datagram Packet by invoking one of the two set
Data () methods.
Void set Data (byte [] buf ) – This method takes as argument a byte array that will
henceforth be used as the Packet’s data storage. Unlike the constructor, this method does not
require a length argument. The method specification states that the previously set length will
be used, unless it is greater than the new buffer length, in which case the buffer length is
used. If the intended use of the set Data (byte[] ) method invocation was to also reset the
length to the size of the new buffer, then a separate call to set Length () method must be
made.
The set Length () methods permits users to change the number of bytes from the byte array
buffer that are considered to hold valid data. If the length specified exceeds the current
buffer’s length, an Illegal Argument Exception will be thrown.
Void set data(byte [ ] buf, int offset, int length) – This method takes a byte array buffer, an
integer offset and an integer length as arguments and sets the datagram’s payload as
described in the constructor, an invalid offset (less than zero, or greater length), or invalid
length (offset + length > buffer, size) will throw illegal argument exception. This second data
( ) method permits users to move the window on an exciting buffer by passing the same byte
array with a different offset and potentiality with a different length.
java.net.DatagramSocket
Instances of the java.net.DataagramSocket class can serve both as client as well as server datagram
sockets. By default, such instances encapsulate VDP sockets, although in principle this behavior
could be changed by invoking set DatagramSocketImplfactory().
Unlike stream sockets, datagram sockets do not have a protocol peer, therefore, the same socket
instance maybe used to send datagrams to any host /port destination as well as receive datagrams
from any host/post source.
Constructors
Because every DatagramSocket instance can be used to receive datagrams it must be associated with
a unique UDP port on the local host. To simplify use when the specific port number assigned is not
important, a non-argument constructor has been provided, whose behavior is to pick an available
UDP port (known as an ephemeral port).
A java.net.SocketException may be thrown at construction time if no free port is available, or due to
some underlying operating system failure. In addition, a runtime SecurityException may be thrown
if the “listen” permission has not been granted. Network permissions are protocol independent.
DatagramSocket() throws SocketException, SecurityException. The other two DatagramSocket
constructors permit users to specify port and optionally the particular interface used for binding.
Both constructors may throw a SocketException if the port is in use, or could not be assigned due to
some operating system failure. Similar to the no-argument constructor, the runtime
SecurityException may be thrown if the “listen” socket permission has not been granted. An
additional error condition may occur in the second constructor if an IP address that does not belong
to the local host is provided. A SocketException is also used to signal this error.
DatagramSocket(int port) throws SocketException,
SecurityException;
DatagramSocket(int port,InetAddress address) throws
SocketException, SecurityException;
Operations
The main role of the DatagramSocket is to send and receive datagrams. Datagrams may be sent by
invoking the send() method with a DatagramPacket instance. The destination host and port can not
be specified in the send() method invocation, therefore they must be set in the DatagramPacket. This
can be achieved by either passing the destination address and port during DatagramPacket instanced
construction, or invoking the DatagramPacket setAddress() and setPort(0 methods.
void send(DatagramPacket packet) throws
IOException,SecurityException, IllegalargumentException;
socket permission only needs to be performed once, at the time the datagram socket is configured to
the destination.
The connect() method configures the socket to transmit datagrams only to the destination specified.
An IllegalArgumentException will be thrown if the address or port arguments are invalid. Invoking
connect() results in a security check for “connect” permission to the specified address and port. If the
security check fails, a SecurityException will be thrown.
void connect(InetAddress address,int port) throws SecurityException,
IllegalArgumentException;
DatagramSocket instances restricted to a single destination may be reverted to the default
unrestricted state by invoking the disconnect() method. It is safe to invoke disconnect() even if the
socket has not been configured using a connect invocation.
void disconnect()
Two methods are provided to query the restriction/connection state of a Datagram Socket.
The getInetAddress() method returns the destination address to which the datagram Socket has been
restricted, or null it if it is in the default unconnected state.
InetAddress getInetAddress();
Similarly, the getPort() method return the destination port to which the datagram socket has been
restricted or – 1 if the port is in default unconnected state.
int getPort();
Datagram Sockets share some common configuration attributes with stream sockets. The blocking
behavior of the receive() method may be controlled by invoking the setSoTimeOut() method.
void setSoTimeOut(int timeOut) throws socket Exception;
int get so Time out () throws Socket Exception;
A non – zero argument configures the DatagramSocket receive() method to throw a
java.io.InterruptedException if a packet has not been received after the given number of
milliseconds. This method is particularly useful because datagrams may be lost and, therefore, the
application could block indefinitely to set a time out. A zero argument to setTimeout() reverts to the
default infinite blocking receive() behavior.
The Datagram Socket class provides method to query the protocol stack’s current send and receive
buffer size. UDP datagrams exceeding the getSendBufferSize() can still be sent, and datagrams
exceeding the getReceiveBufferSize () can still be received. The values only affect the number of
bytes copied at a time. Applications that can predict datagram packet sizes, can use the
setReceiveBufferSize() and setSendBufferSize(). Methods to assist the low – level protocol stack in
reading packets efficiently.
void setSendBufferSize(int Size) throws Socket Exception;
int getSendBufferSize() throws socket Exception;
void getSendBufferSize(int size) throws Socket Exception;
int getReceiveBufferSize() throws socket Exception;
Examples of simple
Examples of Simple UDP Client - Server Application
//Server Program
//TimeServer.java
import java.net.*;
import java.io.*;
import java.util.*;
do
{
socket.receive(inDatagram);
InetAddress destAddress = inDatagram.getAddress();
String destHost = destAddress.getHostName().trim();
int destPort = inDatagram.getPort();
System.out.println("Received datagram from " + destHost +
" at port " + destPort);
String data = new String(inDatagram.getData()).trim();
System.out.println("It contained " + data);
if(data.equalsIgnoreCase("quit"))
finish = true;
outBuffer = time.getBytes();
outDatagram = new
DatagramPacket(outBuffer,outBuffer.length,destAddress,destPort);
socket.send(outDatagram);
System.out.println("Send " + time + " to " + destHost +
" at port " + destPort);
}while(!finish);
}catch(IOException e){ }
}
}
//Client Program
//GetTime.java
import java.net.*;
import java.io.*;
import java.util.*;
byte outBuffer[];
byte inBuffer[] = new byte[256];
DatagramPacket outDatagram;
DatagramPacket inDatagram = new DatagramPacket
(inBuffer, inBuffer.length);
for(int i=0;i<5;i++)
{
outBuffer = new byte[256];
outBuffer = "time".getBytes();
socket.receive(inDatagram);
InetAddress destAddress = inDatagram.getAddress();
String destHost = destAddress.getHostName().trim();
int destPort = inDatagram.getPort();
System.out.println("Received datagram from " + destHost +
" at port " + destPort);
String data = new String(inDatagram.getData());
data = data.trim();
System.out.println("It contained " + data);
System.out.println("\n\n\n");
}
import java.awt.*;
import java.awt.event.*;
import java.net.*;
Thread recThread;
boolean finished = false;
byte outBuffer[];
byte inBuffer[] = new byte[256];
DatagramSocket socket;
DatagramPacket outDatagram;
DatagramPacket inDatagram;
InetAddress destAddress;
String localAddress,data;
int localPort,destPort;
public void init()
{
p1 = new Panel();
p2 = new Panel();
send = new Button(“Go”);
area = new TextArea(20,50);
text = new TextField(25);
add(p1);
add(p2);
p1.add(text);
p1.add(send);
p2.add(area);
send.addActionListener(this);
recThread = new Thread(this);
try
{
socket = new DatagramSocket(2345);
localAddress = InetAddress.
getLocalHost().getHostName().trim();
localPort = socket.getLocalPort();
inDatagram = new DatagramPacket (inBuffer,inBuffer.length);
}
catch(IOException ex)
{
System.ou.println(“Trouble : “ + ex.getMessage());
}
}
public void start()
{
try
{
recThread.start();
}
catch(UninterruptedException ue)
{
System.ou.println(“Trouble : “ + ue.getMessage());
}
}
public void actionPerformed(ActionEvent ae)
{
try
{
area.append(“\n SEND : “ + text.getText());
outBuffer = text.getText().getByte();
outDatagram = new DatagramPacket(outBuffer,
outBuffer.length,destAddress,destPort);
socket.send(outDatagram);
text.setText(“”);
}
catch(IOException ex1)
{
System.out.println(“Trouble : “ + ex1.getMessage());
}
}
try
{
socket = new DatagramSocket(2345);
localAddress = InetAddress.getLocalHost().getHostName().trim();
localPort = socket.getLocalPort();
inDatagram = new DatagramPacket(inBuffer,inBuffer.length);
}
catch(IOException ex)
{
System.ou.println(“Trouble : “ + ex.getMessage());
}
First statement creates a datagram socket socket which listens on port number 2345. Next two
statements are defined to get the environment Variables,that is, localPort number, localHost name
etc. to create the DatagramPacket. In the fourth statement datagram packet is inDatagram is created
using DatagramPacket’s constructor. In this constructor an array of bytes ou Buffer[] is used. The
Datagram Packet will be used to receive a datagram packet from the socket because of the
constructor used to create it. This constructor requires only two arguments: a byte array that contain
client – specific data and the length of the byte array.
After the init () method the thread recThread is started using the start () method of this
program –
try
{
recThread.start();
}
catch(UninterruptedException ue)
{
System.ou.println(“Trouble : “ + ue.getMessage());
}
Now the run method of the server class is as follows –
do
{
socket.receive(inDatagram);
destAddress = inDatagram.getAddress();
destPort = inDatagram.getPort();
data = new String(inDatagram.getData()).trim();
if(data.equalsIgnoreCase(“quit”))
finished = true;
area.append(“\RECEIVE : “ + data);
}while(!finished);
The run method overrides the run in a Thread class and provides the implementation for the thread
recThread. The run method contains a do – while loop that continues as long as until unless the
client program sends the message quit/QUIT/Quit etc.
During each iteration of the loop, the thread waits for a Datagram Packet to arrive over the Datagram
Socket. The packet indicates a message from a client. In response to the client’s message, the Chat
Server App reads a message in a text field from the user and puts it in datagram and sends it over a
socket.
The first statement receives a datagram from the socket (the information received from the client
gets copied into the packet). The receive method waits forever until a packet is received. If no packet
is received, the server makes no further progress and just wits when it received a packet, it reads the
InetAddress and the port number of the packet from its header which is implemented in the next two
statement of the run method. It checks the data whether it is “quit” or not. If it is, and then it
terminates the do – while loop otherwise the message is appended to the text area.
Another main task which is performed by Chat Server App class is send responses the client. This
task is implemented in the action performed method of the server program. It contains following
code –
try
{
area.append(“\n SEND : “ + text.getText());
outBuffer = text.getText().getByte();
outDatagram = new DatagramPacket(outBuffer,
outBuffer.length,destAddress,destPort);
socket.send(outDatagram);
text.setText(“”);
}
In the response to the received message the user can input his message in the text field. After editing
the text field the button Go should be passed. When the button is pressed the relative event is fired
which is implemented with in the action Performed method which overrides the action Performed
method of the java.awt.event class.
The first statement simply appends the text in the text area which ever is being edited in the text
field.
The second statement reads the text field’s text in the bytes form. The next statement creates a new
Datagram Packet object intended for sending a datagram message over the datagram Socket. This
constructor requires four arguments. The first two arguments are the same required by the
constructor used to create receiving datagrams : a byte array “out Buffer”, containing the message
from the sender to the receiver and the length of this array. The next two arguments are different : an
Internet address and a port numbger. These two arguments are the complete address of the
destination of the datagram Packet and must be supplied by the sender of the datagram. These two
argument were read previously from the received datagram packet in the run ()method. The next line
of code sends the Datagram Packet on its way. The last line simply clears the text field.
Finally the stop method of the Chat Server App class –
socket.close();
recThread.stop();
First statement closes the Datagram socket connection next statement stops the running Thread – rec
Thread.
These lines of code fall into category the of house keeping because a well behaved program must
always cleans up after itself. All the resources used by the program must kept free after the
execution. Therefore all the sockets, streams, Thread must be closed or stop.
The ChatClientApp class
The chat client App class implements a client application for the chat server – App class. This
application sends request to the serve, waits for response and when the response is received,
communication starts. The code is as following –
//ChatClientApp.java
import java.lang.*;
import java.util.*;
import java.io.*;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
/*<APPLET CODE=ChatClientApp.java HEIGHT=600 WIDTH=450></APPLET/> */
The ChatClientApp initially set the Applet environment, to use it in web programs. The top portion
of the program declares several local variables for its use. Area of the applet of chat client App is
also divided into two main parts i.e. panels – panel 1 and panel 2. First panel contains the
components to interaction which are send buttons and the text field having size of 25. When user
wants to send some message to the server, he has to type the message in the text field and then click
on the button. Second panel of the applet contain a text area component having 20 rows and 50
columns. This area is used to display the sent and received text.
Like ChatServerApp. Class, ChatClientApp class also performs two main tasks. First send the text
over a socket and receive the packet from the server.
Next, the init method creates a Datagram Socket:
Socket = new Datagram Socket () ;
The client uses a constructor that does not require a port number. This constructor just binds the
Datagram Socket to any available local port. It doesn’t matter what port the client is connected
because the Datagram Packet contain the address information. The server gets the port number from
the Datagram Packets and sends its response to that port.
The ChatClientApp performs two main tasks, for receiving client program creates a thread named
rec Thread. This is also initialized in the init() method.
After the init () method the rec Thread is started in the start () method.
Now the run () method of the client class is as follows –
try{
outBuffer = new byte[256];
firstMessage = ”Hello . . . Sapna calling”;
outBuffer = firstMessage.getBytes();
outDatagram = new DatagramPacket(outBuffer,
outBuffer.length,localAddress,2345);
socket.send(outDatagram);
area.append(“SEND:” + firstMessage);
for(int i=0;i<=5;i++){
socket.receive(inDatagram);
data = new String(inDatagram.getData()).trim();
area.append(“\RECEIVE : “ + data);
}
}catch(IOException ex2){
System.out.println(“Trouble : “ + ex2.getMessage());
}
The run method overrides the run in a Thread class and provides implementation for the rec Thread.
Previously, in the init () method code gets the Internet address for local host named –
localAddress = InetAddress.getLocalHost();
This InetAddress and the port number 23345 (the port number that the server used to create its
Datagram Socket) are then used to create datagram Packet destined for that InetAddress and port
number. Therefore the Datagram packet will be delivered to the chat server App. At start, the first
message is send to server from the client automatically to establish the connection and initiate the
communication.
The code creates a DatagramPacket with and empty byte array. Next, this method implements a for
– loop which executes for 5 times i.e. 0 – 4. This loop client gets a response from the aerver and
displays it in the text area.
To get a response from the server, the client creates a inDatagram packet and used the Datagram –
socket receive method to receive the reply from the server. The receive method waits until a
datagram packet destined for the client comes through the socket. If the server’s reply is somehow
lost, the client will wait forever because of the no – guarantee policy of the datagram model.
When the client receives a reply from the server the client uses the get Data () method to retrieve that
data from the packet. The client then converts the data to a string and displays it in a text area.
Another main task performed by ChatClientApp is send responses to the server. This is implemented
in action Performed method. In the response to the received message the user can input his message
in the text field. After editing the text field the Go button should be pressed. When the button is
pressed the relative event is fired which is implemented in this method which overrides the action
performed method of the java.awt.event class action Performed method creates a new byte array.
Then creates a new datagram packet object intended to send message towards server. To send this
datagram Packet, InetAddress which was read previously in the program and the port number 2345
is used. The actual sending is cone through the send method of the Datagram socket class.
Running the Client & Server Programs
After editing these programs using appropriate editors, these programs should be compiled using
“java c” compiler of the JDK.
C: \javafiles\UDP\Chat> javac Chat Server App.java
C: \Javafiles\UDP\Chat> javac Chat Client App.java
After successful compilation of the program two HTML codes should be written to start the applets
from the web programs, or simply view them using applet viewer.
First, the program would be start using applet viewer like follows –
C: \Javafiles\UDP\chat> appletviewer chat server App.java
The applet will appear on the screen and wait for the socket connection from the client program. For
this program would be start from another host –
C: \Javafiles\UDP\chat>applet viewer Chat Client App.java
The client applet will be appear on the screen. In the server’s applet the first message will appear
sent by the client by the client program. Which would be –
Receive : Hello……….Sapna calling