You are on page 1of 40

NETWORK COMPUTING (RT605)

Module 4
Network Programming with Java - Features of Java Applets & Application Life cycle of applets Security features for applets - Inter applet communication Threads & Thread synchronization TCP/IP Programming with Java Iterative & Concurrent servers. Datagrams, IP multicasting, RMI (Structure and Working of a simple RMI Program only) NETWORK PROGRAMMING Introduction Java provides extensive support for network programming which involves developing applications that run across a computer network. A computer network, often simply referred to as a network, is a group of computers and devices interconnected by communications channels that facilitate communications among users and allows users to share resources. Networks may be classified according to a wide variety of characteristics. A computer network allows sharing of hardware and software resources and information among interconnected devices. A network topology represents its layout or structure from the point of view of data flow. It defines the way in which computers, printers, and other devices are connected, physically and logically. A network topology describes the layout of the wire and devices as well as the paths used by data transmissions. Common types of network topologies include bus, star, ring and mesh. LAN A local area network (LAN) is a network that connects computers and devices in a limited geographical area such as home, school, computer laboratory, office building, or closely positioned group of buildings. Each computer or device on the network is a node. Current wired LANs are most likely to be based on Ethernet technology. The purpose of interconnection would be to share files, share programs and decentralize specialized functions. Another reason for creating a local area network is also to share the use of expensive peripherals such as fast printers, large disks, graphics workstations, etc. Other network types include: Wide area network (WAN) Metropolitan area network (MAN) Virtual private network (VPN) Wireless LANs and WANs (WLAN & WWAN) Protocols HTTP: Hyper Text Transfer Protocol is the protocol that web browsers and servers use to transfer hypertext pages and images. It is quite a simple protocol for a basic page-browsing web server. When a client requests a file from an HTTP server, an action known as a hit, it simply prints the name of the file in a special format to a predefined port and reads back the contents of the file. The server also responds with a status code number to tell the client whether the request can be fulfilled and why. TCP: Transmission Control Protocol provides a reliable, connection-oriented, continuous-stream protocol that client-server applications on the Internet use to communicate with each other. TCP sets up a connection with a remote system by transmitting control information, often known as a handshake, before beginning a communication. To communicate over TCP, a client program and a server program establish a connection to one another. Each program binds a socket to its end of the
Network Computing (SRP) Module 4

connection. To communicate, the client and the server each reads from and writes to the socket bound to the connection. IP: Internet Protocol is the keystone of the TCP/IP suite. The data on the Internet flows through IP packets. IP is termed a connectionless, unreliable protocol. As a connectionless protocol, IP does not exchange control information before transmitting data to a remote system packets are merely sent to the destination with the expectation that they will be treated properly. IP is unreliable because it does not retransmit lost packets or detect corrupted data. An IP address is a 32-bit number, and each standard address is unique on the Internet. Given an IP packet, the information can be routed to the destination based upon the IP address defined in the packet header. UDP: User Datagram Protocol is a connection less, unreliable protocol. UDP is a low-overhead alternative to TCP for host-to-host communications. Message-oriented UDP enables applications to send self-contained messages within UDP datagrams, the unit of UDP transmission. UDP provides the addressing scheme of ports, allowing for many applications to simultaneously send and receive datagrams. UDP has no mechanism for detecting errors, nor retransmitting lost or corrupted information. UDP does not negotiate a connection before transmitting data. Information is sent with the assumption that the recipient will be listening. FTP: File Transfer Protocol is a standard network protocol used to copy a file from one host to another over a TCP/IP-based network, such as the Internet. FTP is built on client-server architecture and utilizes separate control and data connections between the client and server. FTP is most commonly used to download a file from a server using the Internet or to upload a file to a server such as uploading a Web page to a server.

Client / Server Network programming involves 2 types of programs: Client programs and Server programs. Client: The client knows the hostname of the machine on which the server is running and the port number on which the server is listening. The client requests for a connection with the server on the server's machine and port. The client also needs to identify itself to the server so it binds to a local port number that it will use during this connection. Server: A server runs on a specific computer and has a socket that is bound to a specific port number. The server just waits, listening to the socket for a client to make a connection request. There are compute servers, which provide computing power; print servers, which manage a collection of printers; disk servers, which provide networked disk space; and web servers, which store web pages. Proxy Servers A proxy server speaks the client side of a protocol to another server. This is used when clients have certain restrictions on which servers they can connect to. Thus, a client would connect to a proxy server, which did not have such restrictions, and the proxy server would in turn communicate for the client. A proxy server has the additional ability to filter certain requests or cache the results of those requests and reduce the bandwidth demands on a local networks connection to the Internet. Internet Addressing An Internet address is a number that uniquely identifies each computer on the Net. Every computer on the Internet has an address. Originally, all Internet addresses consisted of 32-bit values. This address type was specified by IPv4 (Internet Protocol, version 4). The new addressing scheme called IPv6 (Internet Protocol, version 6) uses a 128-bit value to represent an address. Domain Naming Service (DNS)
Network Computing (SRP) Module 4

The name of an Internet address is called its domain name. It can be seen as a parallel representation of the machines ip address based location.

Java Networking Features Java supports TCP/IP both by extending the already established stream I/O interface and by adding the features required to build I/O objects across the network. Java supports both the TCP and UDP protocol. The java.net package provides many Networking Classes and Interfaces to implement network programming. Classes of java.net package Class ServerSocket Socket SocketAddress InetAddress InetSocketAddress URI URL Description This class implements server sockets. This class implements client sockets. This class represents a socket address with no protocol attachment. This class represents an Internet Protocol (IP) address. It encapsulates both the numerical IP address and the domain name for that address. This class implements an IP socket address (IP address and Port number). This class represents a Uniform Resource Identifier (URI) reference. This class represents a Uniform Resource Locator (URL) reference. This abstract class is the super class of all classes that represent a communication link between the application and the URL. It can be used to inspect the properties of the remote object before actually transporting it locally. Utility class for HTML form encoding. Utility class for HTML form decoding. This class represents a proxy setting, typically a type and a socket address. This class represents a datagram packet. This class represents a socket for sending and receiving datagram packets. This class is used for sending and receiving IP multicast packets. This abstract class is the super class of all classes that read an object from a URLConnection. This class represents an object that knows how to obtain authentication for a network connection.

URLConnection

URLEncoder URLDecoder Proxy DatagramPacket DatagramSocket MulticastSocket ContentHandler Authenticator

Interfaces of java.net package Interface


Network Computing (SRP)

Description
Module 4

ContentHandlerFactory DatagramSocketImplFactory FileNameMap SocketImplFactory SocketOptions URLStreamHandlerFactory

This interface defines a factory for content handlers. This interface defines implementations. a factory for datagram socket

This interface provides a mechanism to map between a file name and a MIME type string. This interface defines a factory for socket implementations. This interface defines methods to get / set socket options. This interface defines a factory for URL stream protocol handlers.

Factory Methods . Factory methods are merely a convention whereby static methods in a class return an instance of that class. For example, the InetAddress class has no visible constructors. To create an InetAddress object, we have to use one of the available factory methods. This is done instead of overloading a constructor with various parameter lists.

Socket A socket is one end-point of a two-way communication link between two programs running on the network. Socket classes are used to represent the connection between a client program and a server program. Sockets are a programming abstraction that isolates our code from the low-level implementations of the TCP/IP protocol stack. The java.net package provides two classes--Socket and ServerSocket--that implement the client side of the connection and the server side of the connection, respectively. A socket is bound to a port number so that the TCP layer can identify the application that data is destined to be sent. Connection oriented sockets are based on TCP Connectionless sockets are based on UDP

Reserved Sockets and Ports Ports can be considered as numbered sockets on a particular machine. Port numbers range from 0 to 65,535. The port numbers ranging from 0 to 1023 are restricted or reserved for the use of well known services such as HTTP and FTP and other system services. These ports are called well known ports. TCP/IP reserves the lower 1,024 ports for specific protocols. 21 is for FTP 23 is for Telnet 25 is for e-mail or SMTP 79 is for finger

Network Computing (SRP)

Module 4

80 is for HTTP 119 is for netnews

Whois The whois port on the InterNIC server can be used to get the IP address and contact information of a registered Internet domain name. We can send the domain name as a command-line argument down the socket. InterNIC will try to look up the argument as a registered Internet domain name, then send back the IP address and contact information for that site. The information contains the Domain Name, Registrar, Whois Server, Referral URL, Name Server and Updated Date.

TCP / IP Socket A socket is a handle to a communications link over the network with another application. A TCP socket uses the TCP protocol, inheriting the behaviour of that transport protocol. Sockets are often used in client/server applications. A centralized service waits for various remote machines to request specific resources, handling each request as it arrives. Four pieces of information are needed to create a TCP socket: The local system's IP address The TCP port number the local application is using The remote system's IP address The TCP port number to which the remote application is responding

Connection:

The server listens for client requests and accepts the connection. Upon acceptance, the server gets a new socket bound to the same local port and also has its remote endpoint set to the address and port of the client. It needs a new socket so that it can continue to listen to the original socket for connection requests while tending to the needs of the connected client.

On the client side, if the connection is accepted, a socket is successfully created and the client can use the socket to communicate with the server. The client and server can now communicate by writing to or reading from their sockets.
Network Computing (SRP) Module 4

An endpoint is a combination of an IP address and a port number. Every TCP connection can be uniquely identified by its two endpoints. The java.net package in the Java platform provides a class, Socket, that implements one side of a two-way connection between our Java program and another program on the network. Additionally, java.net includes the ServerSocket class, which implements a socket that servers can use to listen for and accept connections to clients. There are two kinds of TCP sockets in Java: Client ( Socket ) and Server ( ServerSocket )

TCP/IP Client Sockets TCP/IP sockets are used to implement reliable, bidirectional, persistent, point-to- point, stream-based connections between hosts on the Internet. A socket can be used to connect Javas I/O system to other programs that may reside either on the local machine or on any other machine on the Internet. The Socket class included the java.net package implements the client socket. The Socket class is designed to connect to server sockets and initiate protocol exchanges. The creation of a Socket object implicitly establishes a connection between the client and server. Constructors of the Socket Class Socket( ) : Creates an unconnected socket with system default type. Socket(String hostName, int port) : Creates a socket connecting the local host to the named host and the specified port. It may throw an UnknownHostException or an IOException. Socket(InetAddress ipAddress, int port) : Creates a socket using a preexisting InetAddress object and the specified port. It may throw an IOException. Methods of the Socket Class int getPort( ) : Returns the remote port to which this Socket object is connected. int getLocalPort( ) : Returns the local port to which this Socket object is connected. void bind(SocketAddress bindpoint) : Binds the socket to a local address. void connect(SocketAddress endpoint) : Connects this socket to the server. void close( ) : Closes the socket.

TCP/IP Server Sockets Java has a ServerSocket class (included in java.net) that must be used for creating server applications. The ServerSocket class is designed to be a listener, which waits for clients to connect before doing anything. It is used to create servers that listen for either local or remote client programs to connect to them on published ports. ServerSocket will register itself with the system as having an interest in client connections. The constructors for ServerSocket reflect the port number that we wish to accept connections on. The queue length tells the system how many client connections it can leave pending before it should simply refuse connections. The default is 50. ServerSocket has a method called accept( ), which is a blocking call that will wait for a client to initiate communications, and then return with a normal Socket that is then used for communication with the client. Constructors of the ServerSocket Class ServerSocket( ) : Creates an unbound server socket.
Network Computing (SRP) Module 4

ServerSocket(int port) : Creates a server socket bound to the specified port. The queue length is 50. ServerSocket(int port, int maxQueue, InetAddress localAddress) : Creates a server socket on the specified port with a maximum queue length of maxQueue. On a multihomed host, localAddress specifies the IP address to which this socket binds. Methods of the ServerSocket Class int getLocalPort( ) : Returns the local port on which this Socket object is listening. void bind(SocketAddress endpoint) : Binds the server socket to a specific address (IP and Port). void close( ) : Closes the socket. Socketaccept( ) : Listens for a connection to be made to this socket and accepts it.

Applets Applets are essentially Java applications that run inside a Java-enabled browser, such as Netscape Navigator, Microsoft Internet Explorer, or Mozilla Firefox. They can be considered to be mini programs or applications written in Java. They can be run in a Java supporting browser or in a tool like appletviewer. Java provides the java.applet package to support the creation of Applets. All Applets extend the Applet class present in the java.applet package. The Applets import the java.applet and java.awt packages. Applets are small applications that are accessed on an Internet server, transported over the Internet, automatically installed, and run as part of a Web document. Java applets currently are being used for advertising purposes because they provide the capability to include images, graphics simple animation and sound in a Web advertisement. Applets are generally event driven applications. The execution is based on user interaction. Applets can be embedded into a web page using the <applet> tag. Applets can be embedded into a web page using the <object> tag also. After an applet arrives on the client, it has limited access to resources, so that it can produce an arbitrary multimedia user interface and run complex computations without introducing the risk of viruses or breaching data integrity. When our Java-capable Web browser loads an HTML document containing a reference to an applet, the applet is also loaded and executed. When the browser detects an <applet> tag in an HTML file, it will retrieve the class files for the applet from the server. The bytecode verifier then determines whether the class is a legitimate one. Then the verifier will start to process the class file. The class file is then executed.
Module 4

Network Computing (SRP)

Applets can be included in HTML pages by: <hmtl> <head> <title>Applet Example</title> </head> <body> <applet code="SimpleApplet.class" height = 200 width = 60> </applet> </body> </hmtl> The code value must be set to the name of the main class file of the applet.

Applet Tag Attributes code = appletFile: Code is a required attribute that gives the name of the file containing our applets compiled .class file. This file is relative to the code base URL of the applet, which is the directory that the HTML file was in or the directory indicated by codebase if set. codebase = codebaseURL: Codebase is an optional attribute that specifies the base URL of the applet code. It is the directory that will be searched for the applets executable class file (specified by the CODE tag). The HTML documents URL directory is used as the codebase if this attribute is not specified. The codebase does not have to be on the host from which the HTML document was read. width = pixels: It is a required attribute that gives the width (in pixels) of the applet display area. height = pixels: It is a required attribute that gives the height (in pixels) of the applet display area. alt = alternateText: It is an optional attribute used to specify a short text message that should be displayed if the browser cant currently run Java applets. name = appletInstanceName: It is an optional attribute used to specify a name for the applet instance. Applets must be named in order for other applets on the same page to find them by name and communicate with them. align = alignment: It is an optional attribute that specifies the alignment of the applet. It can take values such as left, right, top, bottom and middle. vspace = pixels: It is an optional attribute that specifies the space, in pixels, above and below the applet. hspace = pixels: It is an optional attribute that specifies the space, in pixels, on each side of the applet.

Network Computing (SRP)

Module 4

param name= AttributeName value=AttributeValue: The param tag allows us to specify applet specific arguments in an HTML page. Applets access their attributes with the getParameter( ) method.

Applets and Applications The most fundamental difference between applets and applications is their operating environment. Java applications are run like conventional applications, from our hard disk. They run within the Java virtual machine, but they appear to be normal applications on our desktop. Applications developed in Java have graphical interfaces and stand on their own. The application does not require a Web browser to execute it. Applications do not require an HTML file to tell them what to load. Applications can be run directly from the command prompt with the use of the Java interpreter. They have the same access to the disk and network as other applications. Java Applets are essentially applications that run inside a Java-enabled browser, such as Netscape Navigator or Microsoft Internet Explorer. Applets must ''live" within a browser or the AppletViewer. They have limited abilities to read or write to our disk, access the network, etc, for security reasons. Java applications can be faster than Java Applets. This is caused by a couple of things. First, an application does not have the overhead of the browser to deal with. In addition, when run as an applet, the browser generally has control of the amount of memory an applet may utilize. As an application, we have complete control over the entire environment the program is running in. These items combine to result in slightly faster execution of Java applications, which are free of some of the burdens of their applet counterparts. The concept called sandbox restricts the operation of an applet. In normal conditions, an applet is forbidden from trying to write or read from our local file system and the applet cannot open an URL to any host on the Internet that it pleases. In contrast, an application is under no such restrictions. Applets may be converted to applications for commercial purposes to suit situations such as restricted connectivity or unavailability of the Internet.

Creating and Using Applets Java provides the java.applet package to support the creation of Applets. The Applets import the java.applet and java.awt packages. All Applets extend the Applet class present in the java.applet package. The java.applet.Applet class extends the AWT class Panel. In turn, Panel extends Container, which extends Component. These classes provide support for Javas window-based, graphical interface. Thus, Applet provides all of the necessary support for window-based activities. Applets interact with the user through the AWT, not through the console-based I/O classes. The applet class we create must be declared as public, because it will be accessed by code that is outside the program.

Eg:

import java.awt.*; import java.applet.*; /* <applet code="SimpleApplet" width=200 height=60> </applet>

Network Computing (SRP)

Module 4

*/ public class SimpleApplet extends Applet { public void paint(Graphics g) { g.drawString(A Simple Applet, 20, 20); } } The paint( ) method is used to display the message in the applet. The Graphics class is a member of the java.awt package. The drawString( ) method provided by the Graphics class is used to display a string content in the applet window. The arguments are the string value and the x, y co-ordinate values. In a Java window, the upper-left corner is location 0,0. void drawString(String message, int x, int y) The applet does not have a main( ) method. Unlike Java programs, applets do not begin execution at main( ). Most applets dont even have a main( ) method. Instead, an applet begins execution when the name of its class is passed to an applet viewer or to a browser.

Steps: 1. Write the source code of the applet and save as a SimpleApplet.java file. 2. Compile the source file using the Java compiler. javac SimpleApplet.java 3. Execute the applet class using the Java appletviewer. appletviewer SimpleApplet.java or appletviewer HTMLFileName.html Output:

Methods used by Applets 1. init( ) The init( ) method is called when an applet begins execution. It is the first method called for any applet. The initialization of the Applet is defined in this method. This method is called only once during the run time of our applet.
Network Computing (SRP) Module 4

10

2. start( ) The start( ) method is called by the browser when an applet should start execution. It is automatically called after init( ) when an applet first begins. It is also called to restart (resume) an applet after it has been stopped. 3. paint( ) The paint( ) method is also called when the applet begins execution. It is used to display the contents of the applet to the applet window (paints the component). The paint( ) method is called each time our applets output must be redrawn. The paint( ) method has one parameter of type Graphics. This parameter will contain the graphics context, which describes the graphics environment in which the applet is running. 4. stop( ) It is called by the browser to suspend execution of the applet. Once stopped, an applet is restarted when the browser calls the start( ) method. 5. destroy( ) It is called by the browser just before an applet is terminated. Our applet may override this method if it needs to perform any cleanup prior to its destruction. Once terminated, the applet cannot be restarted using start( ). The applet is removed completely from memory. 6. play( ) The play(URL url) and play(URL url, String clipName) methods are used to play an audio clip. If an audio clip is found at the location specified by url with the name specified by the clipName, the clip is played. 7. resize( ) The resize(int width, int height) method is called to resize the applet according to the dimensions specified by width and height. 8. update( ) This method is called when our applet has requested that a portion of its window be redrawn. The default version of update( ) first fills an applet with the default background color and then calls paint( ). 9. repaint( ) The repaint( ) method is defined by the AWT. It causes the AWT run-time system to execute a call to our applets update( ) method, which, in its default implementation, calls paint( ). For example, if a part of our applet needs to output a string, it can store this string in a String variable and then call repaint( ). The AWT will then execute a call to paint( ), which can display the stored information using the drawString( ) method.

Applet Skeleton Applets use several methods such as init( ), start( ), paint( ), stop( ) and destroy( ). Default implementations for all of these methods are provided. Applets do not need to override those methods they do not use. If the applets need to implement custom code, they can override these methods.
Network Computing (SRP) Module 4

11

// An Applet skeleton. import java.awt.*; import java.applet.*; /* <applet code="AppletSkel" width=300 height=100> </applet> */ public class AppletSkel extends Applet { // Called first. public void init() { // initialization } /* Called second, after init(). Also called whenever the applet is restarted. */ public void start() { // start or resume execution } // Called when the applet is stopped. public void stop() { // suspends execution } /* Called when applet is terminated. This is the last method executed. */ public void destroy() { // perform shutdown activities } // Called when an applet's window must be restored. public void paint(Graphics g) { // redisplay contents of window } }

Network Computing (SRP)

Module 4

12

Life Cycle of an Applet A Java Applet has a life cycle. This means that throughout the time that an applet exists; certain methods will be called on that applet. As a result, it undergoes a series of changes in its state. Each applet has four major events in its lifetime: Initialization Starting Stopping Destroying

Security Features for Applets Java provides strict security mechanisms to prevent Applets from causing harm to remote or local machines. Applets must ''live" within a browser i.e. it is run within a Java enabled browser such as Internet Explorer. The browser generally has control of the amount of memory an applet may utilize. The Java environment restricts the operation of an applet. An applet can: Draw pictures on a web page. Create a new window and draw in it.
Module 4

Network Computing (SRP)

13

Play sounds. Receive input from the user through the keyboard or the mouse. Make a network connection to the server from which it came and can send to and receive arbitrary data from that server.

An applet cannot: Write data on any of the host's disks. Read any data from the host's disks without the user's permission. In some environments, notably Netscape, an applet cannot read data from the user's disks even with permission. Delete files. Load or execute other programs. Make a network connection to a host on the Internet other than the one from which it was downloaded. Open an URL to any host on the Internet except to the host from which the HTML and class files came. Call the native API directly (though Java API calls may eventually lead back to native API calls). Introduce a virus or trojan horse into the host system.

Inter Applet Communication Inter applet communication can be useful in creating improved visual effects, enhance the contents of the website and provide better user interaction. Applets that share the same Web page within the same browser or Applets loaded in completely different browser windows may communicate with each other through Applets methods. An applet may receive a user input such as a mouse click event and may trigger the redrawing of another applet. Applets must be named in order for other applets on the same page to find them by name and communicate with them. To obtain an applet by name, use getApplet( ), which is defined by the AppletContext interface.

Using Threads in Applets Javas multithreading system is built upon the Thread class, its methods, and its companion interface, Runnable. Threads can be used in Applets to perform concurrent tasks. Commonly threads are used to update the display of an Applet window. It may be achieved by implementing threads to handle the various methods of the Applet such as start( ), stop( ), repaint( ) and update( ). The following example demonstrates the usage of threads in applets. This applet scrolls a message, from right to left, across the applets window. Since the scrolling of the message is a repetitive task, it is performed by a separate thread, created by the applet when it is initialized. Eg: A Simple Banner Applet
Network Computing (SRP) Module 4

14

/* A simple banner applet. This applet creates a thread that scrolls the message contained in msg right to left across the applet's window. */ import java.awt.*; import java.applet.*; /* <applet code="SimpleBanner" width=300 height=50> </applet> */ public class SimpleBanner extends Applet implements Runnable { String msg = " A Simple Moving Banner."; Thread t = null; int state; boolean stopFlag; // Set colors and initialize thread. public void init() { setBackground(Color.cyan); setForeground(Color.red); } // Start thread public void start() { t = new Thread(this); stopFlag = false; t.start(); } // Entry point for the thread that runs the banner. public void run() { char ch; // Display banner for( ; ; ) {
Network Computing (SRP) Module 4

15

try { repaint(); Thread.sleep(250); ch = msg.charAt(0); msg = msg.substring(1, msg.length()); msg += ch; if(stopFlag) break; } catch(InterruptedException e) {} } } // Pause the banner. public void stop() { stopFlag = true; t = null; } // Display the banner. public void paint(Graphics g) { g.drawString(msg, 50, 30); } }

Output:

Network Computing (SRP)

Module 4

16

The class SimpleBanner extends Applet, as expected, and implements Runnable to provide support for threads. The applet will be creating a second thread of execution that will be used to scroll the banner. Inside init( ), the foreground and background colors of the applet are set. After initialization, the AWT run-time system calls start( ) to start the applet running. Inside start( ), a new thread of execution is created and assigned to the Thread variable t. Then, the boolean variable stopFlag, which controls the execution of the applet, is set to false. Next, the thread is started by a call to t.start( ). t.start( ) calls a method defined by Thread, which causes run( ) to begin executing. Inside run( ), the characters in the string contained in msg are repeatedly rotated left. Between each rotation, a call to repaint( ) is made. This eventually causes the paint( ) method to be called and the current contents of msg is displayed. Between each iteration, run( ) sleeps for a quarter of a second. The net effect of run( ) is that the contents of msg is scrolled right to left in a constantly moving display. The stopFlag variable is checked on each iteration. When it is true, the run( ) method terminates. If a browser is displaying the applet when a new page is viewed, the stop( ) method is called, which sets stopFlag to true, causing run( ) to terminate. This is the mechanism used to stop the thread when its page is no longer in view. When the applet is brought back into view, start( ) is once again called, which starts a new thread to execute the banner.

TCP / IP Programming with Java We can create Java programs to communicate between systems connected to a network. The client server model is commonly used to implement network programming. The client side program performs the functions of the client machine and the server side program handles the server machine. The java.net and java.io packages are used to implement the communication process. Refer Java Networking Features, Socket, Ports, TCP/IP Client and Server Sockets.

Client Side 1. The new socket is created by using a socket() constructor 2. The socket attempts to connect to remote host 3. Once the connection is established the local and remote hosts get input and output streams from the socket 4. Close the connection

Server Side 1. A new ServerSocket is created on a particular port 2. Listens for incoming connection attempts on that port 3. Use accept() 4. Block other operations until a client make a network connection 5. Return a socket object
Network Computing (SRP) Module 4

17

6. Get inputstream and outputstream 7. Server and client interacts 8. Server returns to step2.

Eg: Simple Client Server Program The following example demonstrates a simple client - server communication in a network. The client receives a data input and passes it to the server, where it is displayed. Client.java import java.io.*; import java.net.*; // Client Program class Client { Client( ) { PrintWriter pw ; BufferedReader br ; String str ; try { Socket s = new Socket( localhost, 8000 ) ; br = new BufferedReader( new InputStreamReader (System.in) ) ; pw = new PrintWriter( s.getOutputStream( ), true ) ; do { str = br.readLine( ) ; pw.println(str) ; } while( !str.equals("END") ) ; } catch(Exception ex) { System.out.println(ex) ;
Network Computing (SRP) Module 4

18

} } public static void main( String args[ ] ) { new Client( ) ; } }

The socket object s is created to establish a connection with the server named localhost at port number 8000. The name localhost is used when the server resides in the local machine. We have to use the IP address instead of localhost when the server is a remote machine. System.in is used to read the input fed from the clients keyboard. This input stream is converted into an object of the BufferedReader class, using the InputStreamReader class. An object of the PrintWriter class is used to send the output to the server by writing it to the socket. The readLine( ) method is used to read through the contents of the BufferedReader object. The try catch block is used to catch any exceptions or errors that may arise during the execution process.

Server.java import java.io.*; import java.net.*; // Server Program class Server { Server( ) { BufferedReader br ; String str ; try { ServerSocket ss = new ServerSocket( 8000 ) ; 19

Network Computing (SRP)

Module 4

Socket s1 = ss.accept( ) ; br = new BufferedReader(new InputStreamReader ( s1.getInputStream( ) ) ) ; do { str = br.readLine( ) ; System.out.println(str) ; } while( !str.equals("END") ) ; } catch(Exception ex) { System.out.println(ex) ; } } public static void main( String args[ ] ) { new Server( ) ; } }

The server socket object is created to listen to a port (8000) and accept client connections. The socket object s1 is created to establish a connection with the client after the server accepts the request for the connection. The input stream is received through the socket connection from the client. It is then converted into an object of the BufferedReader class, using the InputStreamReader class. The readLine( ) method is used to read through the contents of the BufferedReader object. System.out.println is used to print the received input on to the display screen of the server. The try catch block is used to catch any exceptions or errors that may arise during the execution process.

Output: Client

Network Computing (SRP)

Module 4

20

Server

Example for Bidirectional Client Server Communication Client1.java import java.net.*; import java.io.*; // Client Program class Client1 implements Runnable { Socket ss;
Network Computing (SRP) Module 4

21

BufferedReader b, br ; PrintWriter pw ; Thread t1, t2 ; Client1( ) { try { ss = new Socket( "localhost",8000 ) ; t1 = new Thread(this) ; t2 = new Thread(this) ; t1.start( ) ; System.out.println("Thread1 Started") ; t2.start( ) ; System.out.println("Thread2 Started") ; } catch(Exception ex) { System.out.println(ex) ; } } public void run() { try { String str1="", str2 ; if( Thread.currentThread( ) == t1) { System.out.println("Connected to server") ; b = new BufferedReader( new InputStreamReader (System.in) ) ; pw = new PrintWriter( ss.getOutputStream( ), true) ;

Network Computing (SRP)

Module 4

22

do { str2 = b.readLine() ; pw.println(str2) ; } while( !str2.equals("STOP") ) ; System.out.println("Disconnected") ; } else { br = new BufferedReader(new InputStreamReader (ss.getInputStream( ) ) ) ; do { str1 = br.readLine( ) ; System.out.print("Server: ") ; System.out.println(str1) ; } while( !str1.equals("STOP") ) ; System.out.println("Disconnected"); } } catch(Exception ex) { System.out.println(ex) ; } } public static void main(String args[ ]) { Client1 s = new Client1( ) ; } }

Network Computing (SRP)

Module 4

23

Server1.java import java.net.*; import java.io.*; // Server Program class Server1 implements Runnable { ServerSocket ss ; Socket so ; BufferedReader b, br ; PrintWriter pw ; Thread t1=null, t2=null ; Server1( ) { try { ss = new ServerSocket(8000) ; so = ss.accept( ) ; t1 = new Thread(this) ; t2 = new Thread(this) ; t2.start( ) ; System.out.println("Thread2 Started") ; t1.start( ) ; System.out.println("Thread1 Started") ; System.out.println("Connected to client") ; } catch(Exception ex) { System.out.println(ex) ; } }

Network Computing (SRP)

Module 4

24

public void run() { try { String a="", str ; if( Thread.currentThread( ) != t1 ) { b = new BufferedReader( new InputStreamReader (so.getInputStream( ) ) ) ; do { str = b.readLine( ) ; System.out.print("Client: ") ; System.out.println(str) ; } while( !(str.equals("STOP") ) ) ; System.out.println("Disconnected") ; } else { br = new BufferedReader( new InputStreamReader (System.in) ) ; pw=new PrintWriter( so.getOutputStream( ), true) ; do { a = br.readLine( ) ; pw.println(a) ; } while( !a.equals("STOP") ) ; System.out.println("Disconnected") ; } } catch(Exception ex) {

Network Computing (SRP)

Module 4

25

System.out.println(ex) ; } } public static void main(String args[ ]) { Server1 s=new Server1( ) ; } } Output: Client

Server

Network Computing (SRP)

Module 4

26

Using java.io Package The java.io package provides support for I/O operations in Java. Data is retrieved from an input source. The results of a program are sent to an output destination. The Java I/O Classes and Interfaces defined in the java.io package are used to implement client / server communication and data transfer. The concept of streams was introduced to make programming more uniform for handling disparate data sources or stores. A stream is linked to a physical device by the Java I/O system. The stream classes are usually divided into input and output streams to handle operations on data. This means that an input stream can abstract many different kinds of input: from a disk file, a keyboard, or a network socket. An output stream may refer to the console, a disk file, or a network connection. The read( ) and write( ) methods in these classes are used to read and write bytes / characters of data. They are overridden by derived stream classes. Java 2 defines two types of streams: byte and character. Byte streams provide a convenient means for handling input and output of bytes. InputStream and OutputStream classes are used for byte oriented streams. Character streams provide a convenient means for handling input and output of characters. Reader and Writer classes are used for character oriented streams.

Classes in java.io
Network Computing (SRP) Module 4

27

Class BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter File FileInputStream FileOutputStream FilePermission FileReader FileWriter InputStream InputStreamReader OutputStream OutputStreamWriter PrintStream PrintWriter StringReader StringWriter Writer

Description Buffered input stream. Buffered output stream. Buffered input character stream. Buffered output character stream. Represents a file and describes its properties. Input stream that reads from a file. Output stream that writes to a file. Represents file permissions. Input stream that reads from a file. Output stream that writes to a file. Abstract class that describes stream input. Input stream that translates bytes to characters. Abstract class that describes stream output. Output stream that translates characters to bytes. Output stream that contains print( ) and println( ). Output stream that contains print( ) and println( ). Input stream that reads from a string. Output stream that writes to a string. Abstract class that describes character stream output.

The java.lang package package defines a class called System, which encapsulates several aspects of the run-time environment. System contains three predefined stream variables, in, out, and err. System.out refers to the standard output stream. By default, this is the console. System.in refers to standard input, which is the keyboard by default. System.err refers to the standard error stream, which also is the console by default. System.in is an object of type InputStream. System.out and System.err are objects of type PrintStream.

Reading Console Input

Network Computing (SRP)

Module 4

28

In Java, console input is accomplished by reading from System.in. Using a byte stream to read console input is technically possible but this approach is not recommended. The preferred method of reading console input for Java 2 is to use a character-oriented stream, which makes our program easier to internationalize and maintain. To obtain a character-based stream that is attached to the console, we wrap System.in in a BufferedReader object, to create a character stream. BuffereredReader supports a buffered input stream. BufferedReader(Reader inputReader) The inputReader is the stream that is linked to the instance of BufferedReader that is being created. Reader is an abstract class. One of its concrete subclasses is InputStreamReader, which converts bytes to characters. InputStreamReader(InputStream inputStream) System.in refers to an object of type InputStream, it can be used for inputStream. BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); After this statement executes, br is a character-based stream that is linked to the console through System.in. It can read the characters input from the keyboard. We can use the readLine( ) method of the BufferedReader class to read a string from the keyboard. String str = br.readLine();

Writing Console Output Console output is most easily accomplished with print( ) and println( ) methods defined by the class PrintStream. Even though System.out is a byte stream, using it for simple program output is still acceptable. PrintStream is an output stream derived from OutputStream and it implements the method write( ). The write( ) method can be used to write to the console. Eg: System.out.write(b); // b is an int value representing a character

For real-world programs, the recommended method of writing to the console when using Java is through a PrintWriter stream. PrintWriter is one of the character-based classes. Using a characterbased class for console output makes it easier to internationalize our program. PrintWriter supports the print( ) and println( ) methods for all types including Object. PrintWriter(OutputStream outputStream, boolean flushOnNewline) outputStream is an object of type OutputStream, and flushOnNewline controls whether Java flushes the output stream every time a println( ) method is called. If flushOnNewline is true, flushing automatically takes place. If false, flushing is not automatic. Eg: PrintWriter pw = new PrintWriter(System.out, true); pw.println("This is a string"); Reading and Writing Files

Network Computing (SRP)

Module 4

29

Java provides a number of classes and methods that allow us to read and write files. In Java, all files are byte-oriented. Two of the most often-used stream classes are FileInputStream and FileOutputStream, which create byte streams linked to files. FileInputStream(String fileName) throws FileNotFoundException FileOutputStream(String fileName) throws FileNotFoundException

fileName specifies the name of the file that we want to open. When we create an input stream, if the file does not exist, then FileNotFoundException is thrown. For output streams, if the file cannot be created, then FileNotFoundException is thrown.

Methods read( ) : Each time that it is called, it reads a single byte from the file and returns the byte as an integer value. read( ) returns 1 when the end of the file is encountered. file1.read( ); write( ) : This method writes the byte specified by the argument byteval to the file. file1.write( byteVal ); close( ) : When we are done with a file, we should close it by calling the close( ) method. file1.close( );

Iterative Servers The iterative server handles a request and then returns the results to the client. Any new client requests must wait for the previous request to complete. In this model, the server application holds the socket until all application processing is completed. This means that after a client makes a connection to a server, another client cannot access the listener or the server until the first client is finished. If the transaction takes more time, queues can build up quickly. This type of server is sequential. Iterative servers are fairly simple and are suitable for transactions that do not last long. These can be easily programmed and used to process small, fixed size requests.

Concurrent Servers

Network Computing (SRP)

Module 4

30

A concurrent server does not handle the request itself. A separate thread or sub-process handles request and returns any results to the client. The server is then free to immediately service the next client. The service requests are processed in parallel Hence, the client does not have to wait. This allows a higher degree of transaction concurrency because the listening socket is not held by a single client and can instead listen concurrently to multiple clients. It relies on the operating system for concurrency. It can use the multitasking nature of the operating system. Advantages: 1. Easy to implement. 2. Rely on multi-tasking OS to get concurrency. 3. No Special code is needed to take advantage of multi-processor systems. Disadvantages: 1. Process creation overhead. 2. Potential overloading of computer. 3. Not easy to cache anything. 4. Not easy to share a single database.

Datagrams Datagrams are bundles of information passed between machines. Once the datagram has been released to its intended target, there is no assurance that it will arrive or even that someone will be there to catch it. When the datagram is received, there is no assurance that it hasnt been damaged in transit or that whoever sent it is still there to receive a response. Applications that communicate via datagrams send and receive completely independent packets of information. These clients and servers do not have and do not need a dedicated point-to-point channel. The delivery of datagrams to their destinations is not guaranteed, nor is the order of their arrival. The underlying protocol is UDP which is a connectionless, unreliable and message oriented. UDP is a good choice for applications in which communications can be separated into discrete messages, where a single query from a client invokes a single response from a server. UDP requires much less overhead than TCP/IP. UDP implementation has a limited queue for incoming datagrams. If our application cannot process these datagrams rapidly
Network Computing (SRP) Module 4

31

enough, they will be silently discarded. Neither the sender nor the receiver is notified when datagrams are dropped from a queue overflow. Java implements datagrams on top of the UDP protocol by using two classes in java.net: DatagramPacket: DataGram Packet object is the data container. DatagramSocket: It provides the mechanism used to send and receive the Datagram Packets.

DatagramPacket The DatagramPacket class represents a datagram packet. This class is a wrapper for an array of bytes from which data will be sent or into which data will be received. It also contains the address and port to which the packet will be sent. The object of this class is the data container. Constructors of DatagramPacket DatagramPacket(byte data[ ], int size) It specifies a buffer that will receive data, and the size of a packet. It is used for receiving data over a DatagramSocket. DatagramPacket(byte data[ ], int offset, int size) It allows us to specify an offset into the buffer at which data will be stored. DatagramPacket(byte data[ ], int size, InetAddress ipAddress, int port) It specifies a target address and port, which are used by a DatagramSocket to determine where the data in the packet will be sent. DatagramPacket(byte data[ ], int offset, int size, InetAddress ipAddress, int port) It is used to transmit packets beginning at the specified offset into the data. Methods of DatagramPacket InetAddress getAddress( ) It returns the destination InetAddress, typically used for sending. int getPort( ) It returns the port number. byte[ ] getData( ) It returns the byte array of data contained in the datagram. It is used to retrieve data from the datagram after it has been received. int getLength( ) It returns the length of the valid data contained in the byte array that would be returned from the getData( ) method. This typically does not equal the length of the whole byte array. DatagramSocket
Network Computing (SRP) Module 4

32

This class represents a socket for sending and receiving datagram packets. The actual sending and receiving tasks are accomplished with the DatagramSocket class, which creates a UDP socket. Constructors of DatagramSocket DatagramSocket( ) It creates a socket at an unused short lived port, generally used for client applications. DatagramSocket(int port) It creates a socket and specifies a particular port, which is useful for server applications. DatagramSocket(int port, InetAddress localAddr) It creates a socket bound to a port on machines with multiple IP interfaces. It is used to send and listen for datagrams from one of the IP addresses assigned to the machine. On such a host, datagrams sent to any of the machine's IP addresses are received by a DatagramSocket created with the first two constructors, while the last constructor obtains only datagrams sent to the specific IP address. Methods of DatagramSocket public void send(DatagramPacket p) throws IOException; This method is used to send properly addressed DatagramPacket instances. public synchronized void receive(DatagramPacket p) throws IOException; The transmitted datagram can be received using this method. The receive( ) method blocks until a datagram is received. public synchronized void setSoTimeout(int timeout) throws SocketException; Our application cannot expect receive( ) ever to return unless a timeout is enabled. It is achieved by this method. The timeout is a value in milliseconds. If set to 0, the receive( ) method exhibits an infinite timeout, the default behaviour. When greater than zero, a subsequent receive( ) method invocation waits only the specified timeout before an InterruptedIOException is thrown. public synchronized void close(); After communications through the UDP socket are completed, that socket should be closed using this method. Datagram Server and Client The following example implements a very simple networked communications client and server. Messages are typed into the window at the server and written across the network to the client side, where they are displayed. import java.net.*; class WriteServer { public static int serverPort = 998; public static int clientPort = 999;
Network Computing (SRP) Module 4

33

public static int buffer_size = 1024; public static DatagramSocket ds; public static byte buffer[] = new byte[buffer_size]; public static void TheServer() throws Exception { int pos=0; while (true) { int c = System.in.read(); switch (c) { case -1: System.out.println("Server Quits."); return; case '\r': break; case '\n': ds.send(new DatagramPacket(buffer,pos,InetAddress.getLocalHost(),clientPort)); pos=0; break; default: buffer[pos++] = (byte) c; } } } public static void TheClient() throws Exception { while(true) { DatagramPacket p = new DatagramPacket(buffer, buffer.length); ds.receive(p); System.out.println(new String(p.getData(), 0, p.getLength())); } } public static void main(String args[]) throws Exception { if(args.length == 1) { ds = new DatagramSocket(serverPort); TheServer(); } else { ds = new DatagramSocket(clientPort);

Network Computing (SRP)

Module 4

34

TheClient(); } } } Run: java WriteServer (in one window; this will be the client) java WriteServer 1 (in another window; this will be the server) Output: Anything that is typed in the server window will be sent to the client window after a newline is received.

IP Multicasting Internet Protocol (IP) is the means by which all information on the Internet is transmitted. UDP datagrams are encapsulated within IP packets to send them to the appropriate machines on the network. Most uses of IP involve unicasting: sending a packet from one host to another. IP includes the capability to multicast. With multicasting, a message is addressed to a targeted set of hosts. One message is sent, and the entire group can receive it. Multicasting is particularly suited to high-bandwidth applications, such as sending video and audio over the network, because a separate transmission need not be established. Other possible applications include chat sessions, distributed data storage, and online, interactive games. multicasting can be used by a client searching for an appropriate server on the network; it can send a multicast request, and any listening servers could contact the client to begin a transaction. MulticastSocket class of the java.net package is used for sending and receiving IP multicast packets. MulticastSocket allows you to send or receive UDP datagrams that use multicast IP. The MulticastSocket( ) constructor creates a multicast socket. Then we must create an appropriately formed DatagramPacket addressed to a multicast group. After it is created, the datagram can be sent with the send( ) method, which requires a TTL (time to live) value. The receive( ) method is used just as with the DatagramSocket to obtain incoming messages

To support IP multicasting, a certain range of IP addresses is set aside solely for this purpose. These IP addresses are class D addresses, those within the range of 224.0.0.0 and 239.255.255.255. Each of these addresses is referred to as a multicast group. Any IP packet addressed to that group is received by any machine that has joined that group. Group membership is dynamic and changes over time. When a machine joins a multicast group, it begins accepting messages sent to that IP multicast address. To send a message to a group, a host need not be a member of that group.

Network Computing (SRP)

Module 4

35

Multicast groups are mapped to hardware addresses on interface cards. Thus, IP multicast datagrams that reach an uninterested host can usually be rapidly discarded by the interface card. Multicasting has its limitations, particularly the task of routing multicast packets throughout the Internet. Internet Group Management Protocol (IGMP), is used to manage memberships in a multicast group. A router that supports multi-casting can use IGMP to determine if local machines are subscribed to a particular group and whether to forward on a multicast packet.

RMI ( Remote Method Invocation ) Remote Method Invocation (RMI) allows a Java object that executes on one machine to invoke a method of a Java object that executes on another machine. It allows us to build distributed applications. The Java Remote Method Invocation Application Programming Interface (API), or Java RMI, is a Java application programming interface that performs the object-oriented equivalent of remote procedure calls (RPC). RMI functionality comes in the package java.rmi. RMI allows us to create Java objects whose methods can be invoked by the Virtual Machine on a different computer. Although these objects live and process on a different computer, they are used on the remote machine just like any local object. Any object that can be called remotely must implement the Remote interface. We must create a new interface for our object, that interface must extend Remote. The new interface will contain all of the methods that can be called remotely.

Steps: 1. Define an interface that extends the Remote interface. Each method of this new interface must declare that it will throw a RemoteExecption. 2. Define a class that implements the interface. Because the new interface extends Remote, this fulfills the requirements for making the new class a remote object. The class must provide a means to marshal references to the instances of the class. 3. Generate the stubs and skeletons that are needed for the remote implementations by using the rmic program. 4. Create a client program that will make RMI calls to the server. 5. Start the Registry and run your remote server and client.

A Simple Client/Server Application Using RMI The following example shows a simple client/server application by using RMI. The server receives a request from a client, processes it, and returns a result. 36

Network Computing (SRP)

Module 4

Enter and Compile the Source Code AddServerIntf.java import java.rmi.*; public interface AddServerIntf extends Remote { double add(double d1, double d2) throws RemoteException; } AddServerIntf.java, defines the remote interface that is provided by the server. It contains one method that accepts two double arguments and returns their sum. All remote interfaces must extend the Remote interface, which is part of java.rmi. Remote defines no members. Its purpose is simply to indicate that an interface uses remote methods. All remote methods can throw a RemoteException.

AddServerImpl.java import java.rmi.*; import java.rmi.server.*; public class AddServerImpl extends UnicastRemoteObject implements AddServerIntf { public AddServerImpl() throws RemoteException { } public double add(double d1, double d2) throws RemoteException { return d1 + d2; } }

AddServerImpl.java, implements the remote interface. The implementation of the add( ) method is done here. All remote objects must extend UnicastRemoteObject, which provides the functionality that is needed to make objects available from remote machines.

AddServer.java import java.net.*; import java.rmi.*; public class AddServer { public static void main(String args[]) { try {
Network Computing (SRP) Module 4

37

AddServerImpl addServerImpl = new AddServerImpl(); Naming.rebind("AddServer", addServerImpl); } catch(Exception e) { System.out.println("Exception: " + e); } } }

AddServer.java, contains the main program for the server machine. Its primary function is to update the RMI registry on that machine. This is done by using the rebind( ) method of the Naming class (found in java.rmi). That method associates a name with an object reference. The first argument to the rebind( ) method is a string that names the server as AddServer. Its second argument is a reference to an instance of AddServerImpl.

AddClient.java import java.rmi.*; public class AddClient { public static void main(String args[]) { try { String addServerURL = "rmi://" + args[0] + "/AddServer"; AddServerIntf addServerIntf = (AddServerIntf)Naming.lookup(addServerURL); System.out.println("The first number is: " + args[1]); double d1 = Double.valueOf(args[1]).doubleValue(); System.out.println("The second number is: " + args[2]); double d2 = Double.valueOf(args[2]).doubleValue(); System.out.println("The sum is: " + addServerIntf.add(d1, d2)); } catch(Exception e) { System.out.println("Exception: " + e); } }
Network Computing (SRP) Module 4

38

AddClient.java, implements the client side of this distributed application. AddClient.java requires three command line arguments. The first is the IP address or name of the server machine. The second and third arguments are the two numbers that are to be summed. After we enter all the code, use javac to compile the four source files that we created.

Generate Stubs and Skeletons A stub is a Java object that resides on the client machine. Its function is to present the same interfaces as the remote server. Remote method calls initiated by the client are actually directed to the stub. The stub works with the other parts of the RMI system to formulate a request that is sent to the remote machine. A skeleton is a Java object that resides on the server machine. It works with the other parts of the RMI system to receive requests, perform deserialization, and invoke the appropriate code on the server. If a response must be returned to the client, the process works in reverse.

To generate stubs and skeletons, you use a tool called the RMI compiler, which is invoked from the command line, rmic AddServerImpl This command generates two new files: AddServerImpl_Skel.class (skeleton) and AddServerImpl_Stub.class (stub). When using rmic, be sure that CLASSPATH is set to include the current directory. Install Files on the Client and Server Machines Copy AddClient.class, AddServerImpl_Stub.class, and AddServerIntf.class to a directory on the client machine. Copy AddServerIntf.class, AddServerImpl.class, AddServerImpl_Skel.class, AddServerImpl_Stub.class, and AddServer.class to a directory on the server machine.

Start the RMI Registry on the Server Machine The Java 2 SDK provides a program called rmiregistry, which executes on the server machine. It maps names to object references. First, check that the CLASSPATH environment
Network Computing (SRP) Module 4

39

variable includes the directory in which our files are located. Then, start the RMI Registry from the command line. start rmiregistry A new window is created which must be left open until we are done with the RMI example.

\Start the Server The server code is started from the command line java AddServer

Start the Client The AddClient software requires three arguments: the name or IP address of the server machine and the two numbers that are to be summed together. java AddClient localhost 8 9 or java AddClient 11.12.13.14 8 9 In the first line, the name of the server is provided. The second line uses its IP address (11.12.13.14). Working The application begins by forming a string that follows the URL syntax. This URL uses the rmi protocol. The string includes the IP address or name of the server and the string AddServer. The program then invokes the lookup( ) method of the Naming class. This method accepts one argument, the rmi URL, and returns a reference to an object of type AddServerIntf. All remote method invocations can then be directed to this object. The program continues by displaying its arguments and then invokes the remote add( ) method. The sum is returned from this method and is then printed. Output The first number is: 8 The second number is: 9 The sum is: 17.0

**********************************************************************************

Network Computing (SRP)

Module 4

40

You might also like