0% found this document useful (0 votes)
8 views49 pages

Module –III (2)

This document provides an overview of JDBC (Java Database Connectivity), detailing its implementation, types of JDBC drivers, and how to establish database connections using JDBC. It explains the different driver types (Type 1 to Type 4), their use cases, and the steps required to set up and configure JDBC, including importing packages, registering drivers, and executing SQL statements. Additionally, it covers how to handle exceptions and retrieve data from databases using JDBC methods.

Uploaded by

rekhadivya121
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views49 pages

Module –III (2)

This document provides an overview of JDBC (Java Database Connectivity), detailing its implementation, types of JDBC drivers, and how to establish database connections using JDBC. It explains the different driver types (Type 1 to Type 4), their use cases, and the steps required to set up and configure JDBC, including importing packages, registering drivers, and executing SQL statements. Additionally, it covers how to handle exceptions and retrieve data from databases using JDBC methods.

Uploaded by

rekhadivya121
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 49

MODULE –III

Web Servers and Servlets

JDBC

JDBC Overview – JDBC implementation – Connection class – Statements - Catching Database


Results, handling database Queries. Networking– InetAddress class – URL class- TCP sockets
UDP sockets, Java Beans –RMI.

What is JDBC Driver?


JDBC drivers implement the defined interfaces in the JDBC API, for interacting with your
database server.
For example, using JDBC drivers enable you to open database connections and to interact
with it by sending SQL or database commands then receiving results with Java.
The Java.sql package that ships with JDK, contains various classes with their behaviours
defined and their actual implementaions are done in third-party drivers. Third party vendors
implements the java.sql.Driver interface in their database driver.

JDBC Drivers Types


JDBC driver implementations vary because of the wide variety of operating systems and
hardware platforms in which Java operates. Sun has divided the implementation types into
four categories, Types 1, 2, 3, and 4, which is explained below −

Type 1: JDBC-ODBC Bridge Driver


In a Type 1 driver, a JDBC bridge is used to access ODBC drivers installed on each client
machine. Using ODBC, requires configuring on your system a Data Source Name (DSN) that
represents the target database.
When Java first came out, this was a useful driver because most databases only supported
ODBC access but now this type of driver is recommended only for experimental use or when
no other alternative is available.
The JDBC-ODBC Bridge that comes with JDK 1.2 is a good example of this kind of driver.
Type 2: JDBC-Native API
In a Type 2 driver, JDBC API calls are converted into native C/C++ API calls, which are
unique to the database. These drivers are typically provided by the database vendors and used
in the same manner as the JDBC-ODBC Bridge. The vendor-specific driver must be installed
on each client machine.
If we change the Database, we have to change the native API, as it is specific to a database
and they are mostly obsolete now, but you may realize some speed increase with a Type 2
driver, because it eliminates ODBC's overhead.

The Oracle Call Interface (OCI) driver is an example of a Type 2 driver.

Type 3: JDBC-Net pure Java


In a Type 3 driver, a three-tier approach is used to access databases. The JDBC clients use
standard network sockets to communicate with a middleware application server. The socket
information is then translated by the middleware application server into the call format
required by the DBMS, and forwarded to the database server.
This kind of driver is extremely flexible, since it requires no code installed on the client and a
single driver can actually provide access to multiple databases.
You can think of the application server as a JDBC "proxy," meaning that it makes calls for the client
application. As a result, you need some knowledge of the application server's configuration in order to
effectively use this drivertype.
Your application server might use a Type 1, 2, or 4 driver to communicate with the database,
understanding the nuances will prove helpful.

Type 4: 100% Pure Java


In a Type 4 driver, a pure Java-based driver communicates directly with the vendor's database
through socket connection. This is the highest performance driver available for the database
and is usually provided by the vendor itself.
This kind of driver is extremely flexible, you don't need to install special software on the
client or server. Further, these drivers can be downloaded dynamically.

MySQL's Connector/J driver is a Type 4 driver. Because of the proprietary nature of their
network protocols, database vendors usually supply type 4 drivers.
Which Driver should be Used?
If you are accessing one type of database, such as Oracle, Sybase, or IBM, the preferred
driver type is4.
If your Java application is accessing multiple types of databases at the same time, type 3 is
the preferreddriver.
Type 2 drivers are useful in situations, where a type 3 or type 4 driver is not available yet for
your database.
The type 1 driver is not considered a deployment-level driver, and is typically used for
development and testing purposesonly.

JDBC( Java DatabaseConnectivity):

The first thing you need to do is check that you are set up properly. This involves the
following steps:
1. Install Java and JDBC on yourmachine.
To install both the Java tm platform and the JDBC API, simply follow the instructions for
downloading the latest release of the JDK tm (Java Development Kit tm ). When you
download the JDK, you will get JDBC as well.

2. Install a driver on yourmachine.


Your driver should include instructions for installing it. For JDBC drivers written for specific
DBMSs, installation consists of just copying the driver onto your machine; there is no special
configuration needed.
The JDBC-ODBC Bridge driver is not quite as easy to set up. If you download JDK, you will
automatically get the JDBC-ODBC Bridge driver, which does not itself require any special
configuration. ODBC, however, does. If you do not already have ODBC on your machine,
you will need to see your ODBC driver vendor for information on installation and
configuration.

3. Install your DBMS ifneeded.


If you do not already have a DBMS installed, you will need to follow the vendor's
instructions for installation. Most users will have a DBMS installed and will be working with
an establisheddatabase.

Configuring Database:
Configuring a database is not at all difficult, but it requires special permissions and is
normally done by a database administrator.
First, open the control panel. You might find "Administrative tools" select it, again you may
find shortcut for "Data Sources (ODBC)". When you open the ―Data Source (ODBC)" 32bit
ODBC‖ icon, you‘ll see a "ODBC Data Source Administrator" dialog window with a number
of tabs, including ―User DSN,‖ ―System DSN,‖ ―File DSN,‖ etc., in which ―DSN‖ means
―Data Source Name.‖ Select ―System DSN,‖. and add a new entry there, Select
appropriate driver for the data source or directory where database lives. You can name the
entry anything you want, assume here we are giving our data source name as"MySource".

JDBC Database Access


JDBC was designed to keep simple things simple. This means that the JDBC API makes
everyday database tasks, like simple SELECT statements, very easy.
Import a package java.sql.* : This package provides you set of all classes that enables a
network interface between the front end and back end database.
• DriverManager will create a Connectionobject.
• java.sql.Connection interface represents a connection with a specific database. Methods of
connection is close(), creatStatement(), prepareStatement(), commit(), close() and
prepareCall()
• Statement interface used to interact with database via the execution of SQL statements.
Methods of this interface are executeQuery(), executeUpdate(), execute() andgetResultSet().
• A ResultSet is returned when you execute an SQL statement. It maintains a pointer to a row
within the tablur results. Mehods of this interface are next(), getBoolean(), getByte(),
getDouble(), getString() close() andgetInt().

Establishing a Connection
The first thing you need to do is establish a connection with the DBMS you want to use. This
involves two
steps: (1) loading the driver and (2) making the connection.
Loading Drivers: Loading the driver or drivers you want to use is very simple and involves
just one line of code. If, for example, you want to use the JDBC-ODBC Bridge driver, the
following code will load it
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Your driver documentation will give you the class name to use.Forinstance,

if the class name is jdbc.DriverXYZ , you would load the driver with the following line of
code:
Class.forName("jdbc.DriverXYZ");
Making the Connection: The second step in establishing a connection is to have the
appropriate driver connect to the DBMS. The following line of code illustrates the general
idea:
Connection con = DriverManager.getConnection(url,"myLogin", "myPassword");
If you are using the JDBC-ODBC Bridge driver, the JDBC URL will start with jdbc:odbc: .
The rest of the URL is generally your data source name or database system. So, if you are
using ODBC to access an ODBC data source called "MySource, " for example, your JDBC
URL could be jdbc:odbc:MySource . In place of " myLogin " you put the name you use to
log in to the DBMS; in place of " myPassword " you put your password for the DBMS. So if
you log in to your DBMS with a login name of " scott " and a password of "tiger" just these
two lines of code will establish aconnection:
String url = "jdbc:odbc:MySource";
Connection con = DriverManager.getConnection(url, "scott", "tiger");
The connection returned by the method DriverManager.getConnection is an open
connection you can use to create JDBC statements that pass your SQL statements to the
DBMS. In the
previous example, con is an open connection, and we will use it in the dorth coming
examples.

Creating JDBC Statements


A Statement object is what sends your SQL statement to the DBMS. You simply create a
Statement object and then execute it, supplying the appropriate execute method with the SQL
statement you want to send. For a SELECT statement, the method to use is executeQuery .
For statements that create or modify tables, the method to use is executeUpdate .
It takes an instance of an active connection to create a Statement object. In the following
example, we use our Connection object con to create the Statement object stmt :
Statement stmt = con.createStatement();
At this point stmt exists, but it does not have an SQL statement to pass on to the DBMS. We
need to supply that to the method we use to execute stmt.
For example, in the following code fragment, we supply executeUpdate with the SQL
statement from the example above:
stmt.executeUpdate("CREATE TABLE STUDENT " +
"(S_NAME VARCHAR(32), S_ID INTEGER, COURSE VARCHAR2(10),
YEAR VARCHAR2(3)‖);
Since the SQL statement will not quite fit on one line on the page, we have split it
into two strings concatenated by a plus sign (+) so that it will compile. ExecutingStatements.
Statements that create a table, alter a table, or drop a table are all examples of DDL
statements and are executed with the method executeUpdate. The method executeUpdate is
also used to execute SQL statements that update a table. In practice, executeUpdate is used
far more often to update tables than it is to create them because a table is created once but
may be updated manytimes.
The method used most often for executing SQL statements is executeQuery . This method is
used to execute SELECT statements, which comprise the vast majority of SQL statements.

Entering Data into a Table


We have shown how to create the table STUDENT by specifying the names of the columns
and the data types to be stored in those columns, but this only sets up the structure of the
table. The table does not yet contain any data. We will enter our data into the table one row at
a time, supplying the information to be stored in each column of that row. Note that the
values to be inserted into the columns are listed in the same order that the columns were
declared when the table was created, which is the default order.
The following code inserts one row of data,
Statement stmt = con.createStatement();
stmt.executeUpdate( "INSERT INTO STUDENT VALUES ('xStudent', 501, ‗
B.Tech‘,‘IV‘)");
Note that we use single quotation marks around the student name because it is nested
within double quotation marks. For most DBMSs, the general rule is to alternate
double quotation marks and single quotation marks to indicatenesting.
The code that follows inserts a second row into the table STUDENT . Note that we can just
reuse the Statement object stmt rather than having to create a new one for each execution.
stmt.executeUpdate("INSERT INTO STUDENT " + "VALUES ('yStudent', 502,
‗B.Tech‘.‘III‘)");

Getting Data from a Table


Now that the table STUDENT has values in it, we can write a SELECT statement to access
those values. The star (*) in the following SQL statement indicates that all columns should be
selected. Since there is no WHERE clause to narrow down the rows from which to select, the
following SQL statement selects the whole table:
SQL> SELECT * FROM STUDENT;
Retrieving Values from Result Sets
We now show how you send the above SELECT statements from a program written in the
Java programming language and how you get the results we showed.
JDBC returns results in a ResultSet object, so we need to declare an instance of the class
ResultSet to hold our results. The following code demonstrates declaring the ResultSet
object rs and assigning the results of our earlier query toit:
ResultSet rs = stmt.executeQuery( "SELECT S_NAME, YEAR FROM STUDENT");
The following code accesses the values stored in the current row of rs. Each time the method
next is invoked, the next row becomes the current row, and the loop continues until there are
no more rows in rs .
String query = "SELECT COF_NAME, PRICE FROM STUDENT";
ResultSet rs = stmt.executeQuery(query);
while (rs.next())
{
String s = rs.getString("S_NAME");
Integer i = rs.getInt("S_ID");
String c = rs.getString("COURSE");
String y = rs.getString(―YEAR‖);
System.out.println(i + " " + s + " " + c + " " + y);
}

Updating Tables
Suppose that after a period of time we want update the YEAR column in the table
STUDENT. The SQL statement to update one row might look likethis:
String updateString = "UPDATE STUDENT " +
"SET YEAR = IV WHERE S-NAME LIKE 'yStudent'";
Using the Statement object stmt , this JDBC code executes the SQL statement contained in
updateString :
stmt.executeUpdate(updateString);
Using try and catch Blocks:
Something else all the sample applications include is try and catch blocks. These are the Java
programming language's mechanism for handling exceptions. Java requires that when a
method throws an exception, there be some mechanism to handle it. Generally a catch block
will catch the exception and specify what happens (which you may choose to be nothing). In
the sample code, we use two try blocks and two catch blocks. The first try block contains
the method Class.forName, from the java.lang package. This method throws a
ClassNotFoundException, so the catch block immediately following it deals with that
exception. The second try block contains JDBC methods, which all throw SQLExceptions, so
one catch block at the end of the application can handle all of the rest of the exceptions
that might be thrown because they will all be SQLExceptionobjects.
Retrieving Exceptions
JDBC lets you see the warnings and exceptions generated by your DBMS and by the Java
compiler. To see exceptions, you can have a catch block print them out. For example, the
following two catch blocks from the sample code print out a message explaining the
exception:
Try
{
// Code that could generate an exception goes here.
// If an exception is generated, the catch block below
// will print out information about it.
} catch(SQLException ex)
{
System.err.println("SQLException: " + ex.getMessage());
}

JDBC - Database Connections

After you've installed the appropriate driver, it is time to establish a database connection using
JDBC.

The programming involved to establish a JDBC connection is fairly simple. Here are these
simple four steps −

 Import JDBC Packages − Add import statements to your Java program to


import required classes in your Java code.
 Register JDBC Driver − This step causes the JVM to load the desired
driver implementation into memory so it can fulfill your JDBC requests.
 Database URL Formulation − This is to create a properly formatted address that
points to the database to which you wish to connect.
 Create Connection Object − Finally, code a call to
the DriverManager object's getConnection( ) method to establish actual
database connection.
Import JDBC Packages

The Import statements tell the Java compiler where to find the classes you reference in your code and are
placed at the very beginning of your source code.

To use the standard JDBC package, which allows you to select, insert, update, and delete data in SQL tables,
add the following imports to your source code −

import java.sql.* ; // for standard JDBC programs


import java.math.* ; // for BigDecimal and BigInteger support
Register JDBC Driver

You must register the driver in your program before you use it. Registering the driver is the process by which
the Oracle driver's class file is loaded into the memory, so it can be utilized as an implementation of the
JDBC interfaces.

You need to do this registration only once in your program. You can register a driver in one of two ways.

Approach I - Class.forName()

The most common approach to register a driver is to use Java's Class.forName() method, to dynamically load
the driver's class file into memory, which automatically registers it. This method is preferable because it
allows you to make the driver registration configurable and portable.

The following example uses Class.forName( ) to register the Oracle driver −

try {
Class.forName("oracle.jdbc.driver.OracleDriver");
}
catch(ClassNotFoundException ex)
{ System.out.println("Error: unable to load driver class!");
System.exit(1);
}

You can use getInstance() method to work around noncompliant JVMs, but then you'll have to code for two
extra Exceptions as follows −

try {
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
}
catch(ClassNotFoundException ex)
{ System.out.println("Error: unable to load driver class!");
System.exit(1);
catch(IllegalAccessException ex) {
System.out.println("Error: access problem while
loading!"); System.exit(2);
catch(InstantiationException ex)
{ System.out.println("Error: unable to instantiate
driver!"); System.exit(3);
}
Approach II - DriverManager.registerDriver()

The second approach you can use to register a driver, is to use the
static DriverManager.registerDriver() method.

You should use the registerDriver() method if you are using a non-JDK compliant JVM, such as the one
provided by Microsoft.

The following example uses registerDriver() to register the Oracle driver −

try {
Driver myDriver = new oracle.jdbc.driver.OracleDriver();
DriverManager.registerDriver( myDriver );
}
catch(ClassNotFoundException ex)
{ System.out.println("Error: unable to load driver class!");
System.exit(1);
}
Database URL Formulation

After you've loaded the driver, you can establish a connection using
the DriverManager.getConnection() method. For easy reference, let me list the three overloaded
DriverManager.getConnection() methods −

 getConnection(String url)
 getConnection(String url, Properties prop)
WEB PROGRAMMING

 getConnection(String url, String user, String password)

Here each form requires a database URL. A database URL is an address that points to your database.

Formulating a database URL is where most of the problems associated with establishing a connection occurs.

Following table lists down the popular JDBC driver names and database URL.

RDBMS JDBC driver name URL format

MySQL com.mysql.jdbc.Driver jdbc:mysql://hostname/ databaseName

ORACLE oracle.jdbc.driver.OracleDriver jdbc:oracle:thin:@hostname:port


Number:databaseName

DB2 COM.ibm.db2.jdbc.net.DB2Driver jdbc:db2:hostname:port


Number/databaseName

Sybase com.sybase.jdbc.SybDriver jdbc:sybase:Tds:hostname: port


Number/databaseName

All the highlighted part in URL format is static and you need to change only the remaining part as per your
database setup.

Create Connection Object

We have listed down three forms of DriverManager.getConnection() method to create a connection object.

Using a Database URL with a username and password

The most commonly used form of getConnection() requires you to pass a database URL, a username, and
a password −

Assuming you are using Oracle's thin driver, you'll specify a host:port:databaseName value for the database
portion of the URL.

If you have a host at TCP/IP address 192.0.0.1 with a host name of amrood, and your Oracle listener is
configured to listen on port 1521, and your database name is EMP, then complete database URL would be −

jdbc:oracle:thin:@amrood:1521:EMP

Now you have to call getConnection() method with appropriate username and password to get
a Connection object as follows −

String URL = "jdbc:oracle:thin:@amrood:1521:EMP";


Web Programming Page 74
WEB PROGRAMMING

String USER = "username";


String PASS = "password"
Connection conn = DriverManager.getConnection(URL, USER, PASS);
Using Only a Database URL

A second form of the DriverManager.getConnection( ) method requires only a database URL −

DriverManager.getConnection(String url);

However, in this case, the database URL includes the username and password and has the following general
form − jdbc:oracle:driver:username/password@database

So, the above connection can be created as follows −

String URL = "jdbc:oracle:thin:username/password@amrood:1521:EMP";


Connection conn = DriverManager.getConnection(URL);
Using a Database URL and a Properties Object

A third form of the DriverManager.getConnection( ) method requires a database URL and a Properties object

DriverManager.getConnection(String url, Properties info);

A Properties object holds a set of keyword-value pairs. It is used to pass driver properties to the driver during a
call to the getConnection() method.

To make the same connection made by the previous examples, use the following code −

import java.util.*;

String URL = "jdbc:oracle:thin:@amrood:1521:EMP";


Properties info = new Properties( );
info.put( "user", "username" );
info.put( "password", "password" );

Connection conn = DriverManager.getConnection(URL, info);


Closing JDBC Connections

Web Programming Page 75


WEB PROGRAMMING

At the end of your JDBC program, it is required explicitly to close all the connections to the database to end
each database session. However, if you forget, Java's garbage collector will close the connection when it
cleans up stale objects.

Relying on the garbage collection, especially in database programming, is a very poor programming practice.
You should make a habit of always closing the connection with the close() method associated with
connection object.

To ensure that a connection is closed, you could provide a 'finally' block in your code. A finally block always
executes, regardless of an exception occurs or not.

To close the above opened connection, you should call close() method as follows −

conn.close();

Statements:
There are three types of statements in JDBC namely, Statement, Prepared Statement,
Callable statement.

Statement

The Statement interface represents the static SQL statement. It helps you to create a general purpose SQL
statements using Java.

Creating a statement

You can create an object of this interface using the createStatement() method of the Connection interface.

Create a statement by invoking the createStatement() method as shown below.

Statement stmt = null;

try {

stmt = conn.createStatement( );

...

catch (SQLException e) {

...

finally {

Web Programming Page 76


WEB PROGRAMMING

...

Executing the Statement object

Once you have created the statement object you can execute it using one of the execute methods namely,
execute(), executeUpdate() and, executeQuery().

 execute(): This method is used to execute SQL DDL statements, it returns a boolean value specifying
whether the ResultSet object can be retrieved.
 executeUpdate(): This method is used to execute statements such as insert, update, delete. It returns an
integer value representing the number of rows affected.
 executeQuery(): This method is used to execute statements that returns tabular data (example
SELECT statement). It returns an object of the class ResultSet.
Prepared Statement

The PreparedStatement interface extends the Statement interface. It represents a precompiled SQL statement
which can be executed multiple times. This accepts parameterized SQL quires and you can pass 0 or more
parameters to this query.

Initially, this statement uses place holders “?” instead of parameters, later on, you can pass arguments to these
dynamically using the setXXX() methods of the PreparedStatement interface.

Creating a PreparedStatement

You can create an object of the PreparedStatement (interface) using the prepareStatement() method of the
Connection interface. This method accepts a query (parameterized) and returns a PreparedStatement object.

When you invoke this method the Connection object sends the given query to the database to compile and
save it. If the query got compiled successfully then only it returns the object.

To compile a query, the database doesn’t require any values so, you can use (zero
or more) placeholders (Question marks “?”) in the place of values in the query.

For example, if you have a table named Employee in the database created using the following query:

CREATE TABLE Employee(Name VARCHAR(255), Salary INT NOT NULL, Location

VARCHAR(255));

Then, you can use a PreparedStatement to insert values into it as shown below.

//Creating a Prepared Statement


Web Programming Page 77
WEB PROGRAMMING

String query="INSERT INTO Employee(Name, Salary, Location)VALUES(?, ?, ?)";

Statement pstmt = con.prepareStatement(query);

Setting values to the place holders

The PreparedStatement interface provides several setter methods such as setInt(), setFloat(), setArray(),
setDate(), setDouble() etc.. to set values to the place holders of the prepared statement.

These methods accepts two arguments one is an integer value representing the placement index of the place
holder and the other is an int or, String or, float etc… representing the value you need to insert at that
particular position.

Once you have created a prepared statement object (with place holders) you can set values to the place holders
of the prepared statement using the setter methods as shown below:

pstmt.setString(1, "Amit");

pstmt.setInt(2, 3000);

pstmt.setString(3, "Hyderabad");

Executing the Prepared Statement

Once you have created the PreparedStatement object you can execute it using one of the execute() methods
of the PreparedStatement interface namely, execute(), executeUpdate() and, executeQuery().

 execute(): This method executes normal static SQL statements in the current prepared statement object
and returns a boolean value.
 executeQuery(): This method executes the current prepared statement and returns a ResultSet object.
 executeUpdate(): This method executes SQL DML statements such as insert update or delete in the
current Prepared statement. It returns an integer value representing the number of rows affected.
CallableStatement

The CallableStatement interface provides methods to execute stored procedures. Since the JDBC API
provides a stored procedure SQL escape syntax, you can call stored procedures of all RDBMS in a single
standard way.

Creating a CallableStatement

You can create an object of the CallableStatement (interface) using the prepareCall() method of
the Connection interface.

Web Programming Page 78


WEB PROGRAMMING

This method accepts a string variable representing a query to call the stored procedure and returns
a CallableStatement object.

A CallableStatement can have input parameters or, output parameters or, both. To pass input parameters to the
procedure call you can use place holder and set values to these using the setter methods (setInt(), setString(),
setFloat()) provided by the CallableStatement interface.

Suppose, you have a procedure name myProcedure in the database you can prepare a callable statement as:

//Preparing a CallableStatement

CallableStatement cstmt = con.prepareCall("{call myProcedure(?, ?, ?)}");

Setting values to the input parameters

You can set values to the input parameters of the procedure call using the setter methods.

These accept two arguments one is an integer value representing the placement index of the input parameter
and the other is an int or, String or, float etc… representing the value you need to pass an input parameter to
the procedure.

Note: Instead of index you can also pass the name of the parameter in String

format. cstmt.setString(1, "Raghav");

cstmt.setInt(2, 3000);

cstmt.setString(3, "Hyderabad");

Executing the Callable Statement

Once you have created the CallableStatement object you can execute it using one of the execute() method.

cstmt.execute();

Catching Database Results

The SQL statements that read data from a database query, return the data in a result set. The
SELECT statement is the standard way to select rows from a database and view them in a result set.
The java.sql.ResultSet interface represents the result set of a database query.
A ResultSet object maintains a cursor that points to the current row in the result set. The term "result set"
refers to the row and column data contained in a ResultSet object.
The methods of the ResultSet interface can be broken down into three categories −
 Navigational methods − Used to move the cursor around.
 Get methods − Used to view the data in the columns of the current row being pointed by the cursor.
Web Programming Page 79
WEB PROGRAMMING

 Update methods − Used to update the data in the columns of the current row. The updates can then be
updated in the underlying database as well.
The cursor is movable based on the properties of the ResultSet. These properties are designated when the
corresponding Statement that generates the ResultSet is created.
JDBC provides the following connection methods to create statements with desired ResultSet −
 createStatement(int RSType, int RSConcurrency);
 prepareStatement(String SQL, int RSType, int RSConcurrency);
 prepareCall(String sql, int RSType, int RSConcurrency);
The first argument indicates the type of a ResultSet object and the second argument is one of two ResultSet
constants for specifying whether a result set is read-only or updatable.
Type of ResultSet
The possible RSType are given below. If you do not specify any ResultSet type, you will automatically get
one that is TYPE_FORWARD_ONLY.
Type Description

ResultSet.TYPE_FORWARD_ONLY The cursor can only move forward in the result set.

ResultSet.TYPE_SCROLL_INSENSITIVE The cursor can scroll forward and backward, and


the result set is not sensitive to changes made by
others to the database that occur after the result set
was created.

ResultSet.TYPE_SCROLL_SENSITIVE. The cursor can scroll forward and backward, and


the result set is sensitive to changes made by
others to the database that occur after the result set
was created.
Concurrency of ResultSet
The possible RSConcurrency are given below. If you do not specify any Concurrency type, you will
automatically get one that is CONCUR_READ_ONLY.

Concurrency Description

ResultSet.CONCUR_READ_ONLY Creates a read-only result set. This is the default

ResultSet.CONCUR_UPDATABLE Creates an updateable result set.

All our examples written so far can be written as follows, which initializes a Statement object to create
a forward-only, read only ResultSet object −
try {
Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
}
catch(Exception ex) {
....
}
finally {
Web Programming Page 80
WEB PROGRAMMING

....
}
Navigating a Result Set
There are several methods in the ResultSet interface that involve moving the cursor, including −
S.N. Methods & Description

1 public void beforeFirst() throws SQLException


Moves the cursor just before the first row.

2 public void afterLast() throws SQLException


Moves the cursor just after the last row.

3 public boolean first() throws SQLException


Moves the cursor to the first row.

4 public void last() throws SQLException


Moves the cursor to the last row.

5 public boolean absolute(int row) throws SQLException


Moves the cursor to the specified row.

6 public boolean relative(int row) throws SQLException


Moves the cursor the given number of rows forward or backward, from where it is
currently pointing.

7 public boolean previous() throws SQLException


Moves the cursor to the previous row. This method returns false if the previous row is off
the result set.

8 public boolean next() throws SQLException


Moves the cursor to the next row. This method returns false if there are no more rows in
the result set.

9 public int getRow() throws SQLException


Returns the row number that the cursor is pointing to.

10 public void moveToInsertRow() throws SQLException


Moves the cursor to a special row in the result set that can be used to insert a new row into
the database. The current cursor location is remembered.

11 public void moveToCurrentRow() throws SQLException


Web Programming Page 81
WEB PROGRAMMING

Moves the cursor back to the current row if the cursor is currently at the insert row;
otherwise, this method does nothing

For a better understanding, let us study Navigate - Example Code.


Viewing a Result Set
The ResultSet interface contains dozens of methods for getting the data of the current row.
There is a get method for each of the possible data types, and each get method has two versions −
 One that takes in a column name.
 One that takes in a column index.
For example, if the column you are interested in viewing contains an int, you need to use one of the getInt()
methods of ResultSet −

S.N. Methods & Description

1 public int getInt(String columnName) throws SQLException


Returns the int in the current row in the column named columnName.

2 public int getInt(int columnIndex) throws SQLException


Returns the int in the current row in the specified column index. The column index starts
at 1, meaning the first column of a row is 1, the second column of a row is 2, and so on.

Similarly, there are get methods in the ResultSet interface for each of the eight Java primitive types, as well as
common types such as java.lang.String, java.lang.Object, and java.net.URL.
There are also methods for getting SQL data types java.sql.Date, java.sql.Time, java.sql.TimeStamp,
java.sql.Clob, and java.sql.Blob. Check the documentation for more information about using these SQL data
types.
For a better understanding, let us study Viewing - Example Code.
Updating a Result Set
The ResultSet interface contains a collection of update methods for updating the data of a result set.
As with the get methods, there are two update methods for each data type −
 One that takes in a column name.
 One that takes in a column index.
For example, to update a String column of the current row of a result set, you would use one of the following
updateString() methods −

S.N. Methods & Description

1 public void updateString(int columnIndex, String s) throws SQLException


Changes the String in the specified column to the value of s.

2 public void updateString(String columnName, String s) throws SQLException

Web Programming Page 82


WEB PROGRAMMING

Similar to the previous method, except that the column is specified by its name instead of
its index.

There are update methods for the eight primitive data types, as well as String, Object, URL, and the SQL data
types in the java.sql package.
Updating a row in the result set changes the columns of the current row in the ResultSet object, but not in the
underlying database. To update your changes to the row in the database, you need to invoke one of the
following methods.

S.N. Methods & Description

1 public void updateRow()


Updates the current row by updating the corresponding row in the database.

2 public void deleteRow()


Deletes the current row from the database

3 public void refreshRow()


Refreshes the data in the result set to reflect any recent changes in the database.

4 public void cancelRowUpdates()


Cancels any updates made on the current row.

5 public void insertRow()


Inserts a row into the database. This method can only be invoked when the cursor is
pointing to the insert row.

Networking– InetAddress class

Java InetAddress class represents an IP address. The java.net.InetAddress class provides methods to get the
IP of any host name for example www.javatpoint.com, www.google.com, www.facebook.com, etc.

An IP address is represented by 32-bit or 128-bit unsigned number. An instance of InetAddress represents the
IP address with its corresponding host name. There are two types of addresses: Unicast and Multicast. The
Unicast is an identifier for a single interface whereas Multicast is an identifier for a set of interfaces.

Moreover, InetAddress has a cache mechanism to store successful and unsuccessful host name resolutions.

IP Address
o An IP address helps to identify a specific resource on the network using a numerical representation.
o Most networks combine IP with TCP (Transmission Control Protocol). It builds a virtual bridge among
the destination and the source.

Web Programming Page 83


WEB PROGRAMMING

There are two versions of IP address:

1. IPv4

IPv4 is the primary Internet protocol. It is the first version of IP deployed for production in the ARAPNET in
1983. It is a widely used IP version to differentiate devices on network using an addressing scheme. A 32-bit
addressing scheme is used to store 232 addresses that is more than 4 million addresses.

Features of IPv4:

o It is a connectionless protocol.
o It utilizes less memory and the addresses can be remembered easily with the class based addressing
scheme.
o It also offers video conferencing and libraries.

2. IPv6

IPv6 is the latest version of Internet protocol. It aims at fulfilling the need of more internet addresses. It
provides solutions for the problems present in IPv4. It provides 128-bit address space that can be used to form
a network of 340 undecillion unique IP addresses. IPv6 is also identified with a name IPng (Internet Protocol
next generation).

Features of IPv6:

o It has a stateful and stateless both configurations.


o It provides support for quality of service (QoS).
o It has a hierarchical addressing and routing infrastructure.

TCP/IP Protocol
o TCP/IP is a communication protocol model used connect devices over a network via internet.
o TCP/IP helps in the process of addressing, transmitting, routing and receiving the data packets over the
internet.
o The two main protocols used in this communication model are:
1. TCP i.e. Transmission Control Protocol. TCP provides the way to create a communication
channel across the network. It also helps in transmission of packets at sender end as well as
receiver end.
2. IP i.e. Internet Protocol. IP provides the address to the nodes connected on the internet. It uses
a gateway computer to check whether the IP address is correct and the message is forwarded
correctly or not.

Java InetAddress Class Methods

Web Programming Page 84


WEB PROGRAMMING

Method Description

public static InetAddress getByName(String host) throws It returns the instance of InetAddress containing
UnknownHostException LocalHost IP and name.

public static InetAddress getLocalHost() throws It returns the instance of InetAdddress containing
UnknownHostException local host name and address.

public String getHostName() It returns the host name of the IP address.

public String getHostAddress() It returns the IP address in string format.


Example of Java InetAddress Class

Let's see a simple example of InetAddress class to get ip address of www.javatpoint.com website.

InetDemo.java

import java.io.*;
1.
import java.net.*;
2.
public class InetDemo{
3.
public static void main(String[] args){
4.
try{
5.
InetAddress ip=InetAddress.getByName("www.javatpoint.com");
6.
7.
System.out.println("Host Name: "+ip.getHostName());
8.
System.out.println("IP Address: "+ip.getHostAddress());
9.
0. }catch(Exception e){System.out.println(e);}
1
1. }
1
2. }
1 Test it Now

Output:

Host Name: www.javatpoint.com


IP Address: 172.67.196.82
Program to demonstrate methods of InetAddress class

InetDemo2.java

import java.net.Inet4Address;
1.
import java.util.Arrays;
2.
import java.net.InetAddress;
3.
public class InetDemo2
4.
{
5. Web Programming Page 85
WEB PROGRAMMING

6. public static void main(String[] arg) throws Exception


7. {
8. InetAddress ip = Inet4Address.getByName("www.javatpoint.com");
9. InetAddress ip1[] = InetAddress.getAllByName("www.javatpoint.com");
10. byte addr[]={72, 3, 2, 12};
11. System.out.println("ip : "+ip);
12. System.out.print("\nip1 : "+ip1);
13. InetAddress ip2 = InetAddress.getByAddress(addr);
14. System.out.print("\nip2 : "+ip2);
15. System.out.print("\nAddress : " +Arrays.toString(ip.getAddress()));
16. System.out.print("\nHost Address : " +ip.getHostAddress());
17. System.out.print("\nisAnyLocalAddress : " +ip.isAnyLocalAddress());
18. System.out.print("\nisLinkLocalAddress : " +ip.isLinkLocalAddress());
19. System.out.print("\nisLoopbackAddress : " +ip.isLoopbackAddress());
20. System.out.print("\nisMCGlobal : " +ip.isMCGlobal());
21. System.out.print("\nisMCLinkLocal : " +ip.isMCLinkLocal());
22. System.out.print("\nisMCNodeLocal : " +ip.isMCNodeLocal());
23. System.out.print("\nisMCOrgLocal : " +ip.isMCOrgLocal());
24. System.out.print("\nisMCSiteLocal : " +ip.isMCSiteLocal());
25. System.out.print("\nisMulticastAddress : " +ip.isMulticastAddress());
26. System.out.print("\nisSiteLocalAddress : " +ip.isSiteLocalAddress());
27. System.out.print("\nhashCode : " +ip.hashCode());
28. System.out.print("\n Is ip1 == ip2 : " +ip.equals(ip2));
29. }
30. }
31. OUTPUT

Web Programming Page 86


WEB PROGRAMMING

URL class
JDBC provides the URL to identify the database, so we can easily recognize the required
driver and we can connect it. Basically JDBC URL we can use as database connection URL
as per user requirement. When the driver loaded successfully we need to specify the required
database connection URL to connect the database that the user wants. We know that the
JDBC URL always starts with the JDBC keyword for the database connection; basically, the
URL depends on the JDBC driver. We also need to provide the different parameters with the
JDBC URL that is port number, hostname, database name, user name, and password, etc.

Syntax:

specified protocol name//[specified host name][/specified database name][username and password]

How URL works in JDBC?

For establishing a connection with the database we need to follow the same step as follows.

Import JDBC Packages: First step we need to import the JDBC packages into the Java program that we require

the class in code.

Register the JDBC Driver: After importing the class we need to load the JVM to fulfill that is it loaded the

required driver as well as memory for JDBC request.

Database URL Formation: In this step, we need to provide the correct parameter to connect the specified

database that we already discussed in the above point.

Create the Connection Object: After the formation of the URL, we need to create the object of connection that

means we can call the DriverManager with grtConnection() methods to establish the connection with a

specified database name.

Now let’s see in detail how we can import the JDBC Driver as follows.

Web Programming Page 87


WEB PROGRAMMING

Basically, the import statement is used to compile the java program and is also used to find the classes that

are helpful to implement the source code as per user requirements. By using these standard packages, we can

perform different operations such as insertion, delete and update as per user requirements.

import java.sql.*;

Now let’s see how we can register the JDBC Driver as follows.

We just need to import the driver before using it. Enlisting the driver is the cycle by which the Oracle driver’s

class document is stacked into the memory, so it tends to be used as an execution of the JDBC interfaces.

You need to do this enrollment just a single time in your program. You can enlist a driver in one of two

different ways.

1. By using Class.forName():

The most widely recognized way to deal with registering a driver is to utilize Java’s Class.forName()

technique, to progressively stack the driver’s class document into memory, which naturally enlists it. This

technique is ideal since it permits you to make the driver enrollment configurable and compact.

2. By using DriverManager.registerDriver():

The second methodology you can use to enroll a driver is to utilize the static DriverManager.registerDriver()

strategy.

You should utilize the registerDriver() technique in case you are utilizing a non-JDK agreeable JVM, for

example, the one given by Microsoft.

Web Programming Page 88


WEB PROGRAMMING

After you’ve stacked the driver, you can set up an association utilizing the

DriverManager.getConnection() technique. JDBC provides the different JDBC drivers for the different

database systems and we can utilize them as per the user requirement.

1. MySQL JDBC URL format:


This is the first JDBC URL format that can be used in MySQL to establish the connection with the

required database name. The format of this URL is as follows.

(Connection con_obj = DriverManager.getConnection(specifed_jdbcUrl, user defined username, user defined

password))

Explanation

In the above format, we use DriverManager.getConnection method to establish the connection with the

database; here we need to pass the specified JDBC URL as well as we need to pass the username and

password. The username and password fields are depending on the user. In JDBC URL we need to pass all

parameters that we require to make the connection such as database name, protocol, etc.

2. Microsoft SQL Server URL format:


This is another famous URL format for the database system. Suppose we need to connect to the Microsoft

SQL Server from a Java application at that time we can use the below-mentioned format as follows.

jdbc:sqlserver://[specified serverName[\ specified instanceName][:required portNumber]][;property(that user

defined properties)]

Explanation

Web Programming Page 89


WEB PROGRAMMING

In the above syntax, we need to mention the server name that is the address of the server, or we can say that

domain name or IP address. Also, we need to mention the instance name for server connection if we leave then

it uses the default. In the same way, we can use port numbers and properties.

3. PostgreSQL JDBC URL format:


PostgreSQL is a famous open-source database system. So we can use the below-mentioned JDBC format as

follows.

Jdbc:postgresql://hostname:port number/specified database name and properties.

Examples
Now let’s see different examples of JDBC URLs for better understanding as follows.

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.Statement;

public class connection_t {

public static void main(String args[]){

String m_url = " jdbc:mysql://localhost ";

Connection con_obj = DriverManager.getConnection(m_url, "root", "root");

System.out.println("Connection successfully established with database. . .");

Explanation
Web Programming Page 90
WEB PROGRAMMING

In the above example, we import the dependencies that are required to establish the connection with the

database such as SQL. connection, SQL.DriverManger etc. After that, we import the class as shown. Here we

also mentioned a connection string with connection parameters such as DriverManager.getConnection()

method as shown. The final output or end result of the above example we illustrated by using the following

screenshot as follows.

In the same way, we can connect to the Microsoft server and PostgreSQL as per our requirements

Program A program is an executable file residing on a disk in a directory. A program is read into
memory and is executed by the kernel as ad result of an exec() function. The exec() has six
variants, but we only consider the simplest one (exec()) in this course.

Process An executing instance of a program is called a process. Sometimes, task is used instead
of process with the same meaning. UNIX guarantees that every process has a unique identifier
called the process ID. The process ID is always a non-negative integer.

File descriptors File descriptors are normally small non-negative integers that the kernel uses to
identify the files being accessed by a particular process. Whenever it opens an existing file or
creates a new file, the kernel returns a file descriptor that is used to read or write the file. As we
will see in this course, sockets are based on a very similar mechanism (socket descriptors).

The client-server model

The client-server model is one of the most used communication paradigms in networked systems.
Clients normally communicates with one server at a time. From a server’s perspective, at any
point in time, it is not unusual for a server to be communicating with multiple clients. Client need
to know of the existence of and the address of the server, but the server does not need to know
the address of (or even the existence of) the client prior to the connection being established

Client and servers communicate by means of multiple layers of network protocols. In this course
we will focus on the TCP/IP protocol suite.

The scenario of the client and the server on the same local network (usually called LAN, Local
Area Network) is shown in Figure 1

Web Programming Page 91


WEB PROGRAMMING

Figure 1: Client and server on the same Ethernet communicating using TCP/IP

The client and the server may be in different LANs, with both LANs connected to a Wide Area Network
(WAN) by means of routers. The largest WAN is the Internet, but companies may have their own WANs.
This scenario is depicted in Figure 2.

Web Programming Page 92


WEB PROGRAMMING

Figure 2: Client and server on different LANs connected through WAN/Internet.

The flow of information between the client and the server goes down the protocol stack on one side, then
across the network and then up the protocol stack on the other side.

User Datagram Protocol (UDP)

UDP is a simple transport-layer protocol. The application writes a message to a UDP socket, which is then
encapsulated in a UDP datagram, which is further encapsulated in an IP datagram, which is sent to the
destination.

There is no guarantee that a UDP will reach the destination, that the order of the datagrams will be preserved
across the network or that datagrams arrive only once.

The problem of UDP is its lack of reliability: if a datagram reaches its final destination but the checksum
detects an error, or if the datagram is dropped in the network, it is not automatically retransmitted.

Each UDP datagram is characterized by a length. The length of a datagram is passed to the receiving
application along with the data.

No connection is established between the client and the server and, for this reason, we say that UDP provides
a connection-less service.

It is described in RFC 768.

Transmission Control Protocol (TCP)

TCP provides a connection oriented service, since it is based on connections between clients and servers.

TCP provides reliability. When a TCP client send data to the server, it requires an acknowledgement in
return. If an acknowledgement is not received, TCP automatically retransmit the data and waits for a longer
period of time.

We have mentioned that UDP datagrams are characterized by a length. TCP is instead a byte-stream
protocol, without any boundaries at all.

TCP is described in RFC 793, RFC 1323, RFC 2581 and RFC 3390.

Socket addresses

IPv4 socket address structure is named sockaddr_in and is defined by including the <netinet/in.h> header.

The POSIX definition is the following:

struct in_addr{
in_addr_t s_addr; /*32 bit IPv4 network byte ordered address*/
};

Web Programming Page 93


WEB PROGRAMMING

struct sockaddr_in {
uint8_t sin_len; /* length of structure (16)*/
sa_family_t sin_family; /* AF_INET*/
in_port_t sin_port; /* 16 bit TCP or UDP port number */
struct in_addr sin_addr; /* 32 bit IPv4 address*/
char sin_zero[8]; /* not used but always set to zero */
};

The uint8_t datatype is unsigned 8-bit integer.

Generic Socket Address Structure

A socket address structure is always passed by reference as an argument to any socket functions. But any
socket function that takes one of these pointers as an argument must deal with socket address structures from
any of the supported protocol families.

A problem arises in declaring the type of pointer that is passed. With ANSI C, the solution is to use void * (the
generic pointer type). But the socket functions predate the definition of ANSI C and the solution chosen was
to define a generic socket address as follows:

struct sockaddr
{ uint8_t sa_len;
sa_family_t sa_family; /* address family: AD_xxx value */
char sa_data[14];
};

Host Byte Order and Network Byte Order Conversion

There are two ways to store two bytes in memory: with the lower-order byte at the starting address (little-
endian byte order) or with the high-order byte at the starting address (big-endian byte order). We call them
collectively host byte order. For example, an Intel processor stores the 32-bit integer as four consecutives
bytes in memory in the order 1-2-3-4, where 1 is the most significant byte. IBM PowerPC processors would
store the integer in the byte order 4-3-2-1.

Networking protocols such as TCP are based on a specific network byte order. The Internet protocols use big-
endian byte ordering.

The htons(), htonl(), ntohs(), and ntohl() Functions

The follwowing functions are used for the conversion:

#include <netinet/in.h>

uint16_t htons(uint16_t host16bitvalue);

uint32_t htonl(uint32_t host32bitvalue);

uint16_t ntohs(uint16_t net16bitvalue);

Web Programming Page 94


WEB PROGRAMMING

uint32_t ntohl(uint32_t net32bitvalue);

The first two return the value in network byte order (16 and 32 bit, respectively). The latter return the value in
host byte order (16 and 32 bit, respectively).

TCP Socket API

The sequence of function calls for the client and a server participating in a TCP connection is presented in
Figure 3.

Web Programming Page 95


WEB PROGRAMMING

Figure 3: TCP client-server.

As shown in the figure, the steps for establishing a TCP socket on the client side are the following:

 Create a socket using the socket() function;


 Connect the socket to the address of the server using the connect() function;
 Send and receive data by means of the read() and write() functions.
 Close the connection by means of the close() function.

The steps involved in establishing a TCP socket on the server side are as follows:

 Create a socket with the socket() function;


 Bind the socket to an address using the bind() function;
 Listen for connections with the listen() function;
 Accept a connection with the accept() function system call. This call typically blocks until a
client connects with the server.
 Send and receive data by means of send() and receive().
 Close the connection by means of the close() function.

The socket() Function

The first step is to call the socket function, specifying the type of communication protocol (TCP based on
IPv4, TCP based on IPv6, UDP).

The function is defined as follows:

#include <sys/socket.h>

int socket (int family, int type, int protocol);

where family specifies the protocol family (AF_INET for the IPv4 protocols), type is a constant described the
type of socket (SOCK_STREAM for stream sockets and SOCK_DGRAM for datagram sockets.

The function returns a non-negative integer number, similar to a file descriptor, that we
define socket descriptor or -1 on error.

The connect() Function

The connect() function is used by a TCP client to establish a connection with a TCP server/

The function is defined as follows:

#include <sys/socket.h>

int connect (int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);

where sockfd is the socket descriptor returned by the socket function.


Web Programming Page 96
WEB PROGRAMMING

The function returns 0 if the it succeeds in establishing a connection (i.e., successful TCP three-way
handshake, -1 otherwise.

The client does not have to call bind() in Section before calling this function: the kernel will choose both an
ephemeral port and the source IP if necessary.

The bind() Function

The bind() assigns a local protocol address to a socket. With the Internet protocols, the address is the
combination of an IPv4 or IPv6 address (32-bit or 128-bit) address along with a 16 bit TCP port number.

The function is defined as follows:

#include <sys/socket.h>

int bind(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);

zwhere sockfd is the socket descriptor, servaddr is a pointer to a protocol-specific address and addrlen is the
size of the address structure.

bind() returns 0 if it succeeds, -1 on error.

This use of the generic socket address sockaddr requires that any calls to these functions must cast the
pointer to the protocol-specific address structure. For example for and IPv4 socket structure:

struct sockaddr_in serv; /* IPv4 socket address structure */

bind(sockfd, (struct sockaddr*) &serv, sizeof(serv))

A process can bind a specific IP address to its socket: for a TCP client, this assigns the source IP address that
will be used for IP datagrams sent on the sockets. For a TCP server, this restricts the socket to receive
incoming client connections destined only to that IP address.

Normally, a TCP client does not bind an IP address to its socket. The kernel chooses the source IP socket is
connected, based on the outgoing interface that is used. If a TCP server does not bind an IP address to its
socket, the kernel uses the destination IP address of the incoming packets as the server’s source address.

bind() allows to specify the IP address, the port, both or neither.

The table below summarizes the combinations for IPv4.

IP Address IP Port Result


INADDR_ANY 0 Kernel chooses IP address and port
INADDR_ANY non zero Kernel chooses IP address, process specifies port
Local IP address 0 Process specifies IP address, kernel chooses port
Local IP address non zero Process specifies IP address and port

Note, the local host address is 127.0.0.1; for example, if you wanted to run your echoServer (see later) on your
local machine the your client would connect to 127.0.0.1 with the suitable port.
Web Programming Page 97
WEB PROGRAMMING

The listen() Function

The listen() function converts an unconnected socket into a passive socket, indicating that the kernel should
accept incoming connection requests directed to this socket. It is defined as follows:

#include <sys/socket.h>

int listen(int sockfd, int backlog);

where sockfd is the socket descriptor and backlog is the maximum number of connections the kernel should
queue for this socket. The backlog argument provides an hint to the system of the number of outstanding
connect requests that it should enqueue on behalf of the process. Once the queue is full, the system will reject
additional connection requests. The backlog value must be chosen based on the expected load of the server.

The function listen() return 0 if it succeeds, -1 on error.

The accept() Function

The accept() is used to retrieve a connect request and convert that into a request. It is defined as follows:

#include <sys/socket.h>

int accept(int sockfd, struct sockaddr *cliaddr,


socklen_t *addrlen);

where sockfd is a new file descriptor that is connected to the client that called the connect().
The cliaddr and addrlen arguments are used to return the protocol address of the client. The new socket
descriptor has the same socket type and address family of the original socket. The original socket passed
to accept() is not associated with the connection, but instead remains available to receive additional connect
requests. The kernel creates one connected socket for each client connection that is accepted.

If we don’t care about the client’s identity, we can set the cliaddr and addrlen to NULL. Otherwise, before
calling the accept function, the cliaddr parameter has to be set to a buffer large enough to hold the address
and set the interger pointed by addrlen to the size of the buffer.

The send() Function

Since a socket endpoint is represented as a file descriptor, we can use read and write to communicate with a
socket as long as it is connected. However, if we want to specify options we need another set of functions.

For example, send() is similar to write() but allows to specify some options. send() is defined as follows:

#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t nbytes, int flags);

where buf and nbytes have the same meaning as they have with write. The additional argument flags is used to
specify how we want the data to be transmitted. We will not consider the possible options in this course. We
will assume it equal to 0.
Web Programming Page 98
WEB PROGRAMMING

The function returns the number of bytes if it succeeds, -1 on error.

The receive() Function

The recv() function is similar to read(), but allows to specify some options to control how the data
are received. We will not consider the possible options in this course. We will assume it equal to 0.

receive is defined as follows:

#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags);

The function returns the length of the message in bytes, 0 if no messages are available and peer had done an
orderly shutdown, or -1 on error.

The close() Function

The normal close() function is used to close a socket and terminate a TCP socket. It returns 0 if it succeeds, -1
on error. It is defined as follows:

#include <unistd.h>

int close(int sockfd);

UDP Socket API

There are some fundamental differences between TCP and UDP sockets. UDP is a connection-less,
unreliable, datagram protocol (TCP is instead connection-oriented, reliable and stream based). There are some
instances when it makes to use UDP instead of TCP. Some popular applications built around UDP are DNS,
NFS, SNMP and for example, some Skype services and streaming media.

Figure 4 shows the the interaction between a UDP client and server. First of all, the client does not establish a
connection with the server. Instead, the client just sends a datagram to the server using the sendto function
which requires the address of the destination as a parameter. Similarly, the server does not accept a connection
from a client. Instead, the server just calls the recvfrom function, which waits until data arrives from some
client. recvfrom returns the IP address of the client, along with the datagram, so the server can send a response
to the client.

As shown in the Figure, the steps of establishing a UDP socket communication on the client side are as
follows:

 Create a socket using the socket() function;


 Send and receive data by means of the recvfrom() and sendto() functions.

The steps of establishing a UDP socket communication on the server side are as follows:

 Create a socket with the socket() function;


 Bind the socket to an address using the bind() function;
 Send and receive data by means of recvfrom() and sendto().
Web Programming Page 99
WEB PROGRAMMING

Figure 4: UDP client-server.

In this section, we will describe the two new functions recvfrom() and sendto().

The recvfrom() Function

This function is similar to the read() function, but three additional arguments are required.
The recvfrom() function is defined as follows:

#include <sys/socket.h>

ssize_t recvfrom(int sockfd, void* buff, size_t nbytes,


int flags, struct sockaddr* from,
socklen_t *addrlen);

The first three arguments sockfd, buff, and nbytes, are identical to the first three arguments
of read and write. sockfd is the socket descriptor, buff is the pointer to read into, and nbytes is number of bytes
to read. In our examples we will set all the values of the flags argument to 0. The recvfrom function fills in the

Web Programming Page 100


WEB PROGRAMMING

socket address structure pointed to by from with the protocol address of who sent the datagram. The number of
bytes stored in the socket address structure is returned in the integer pointed by addrlen.

The function returns the number of bytes read if it succeeds, -1 on error.

The sendto() Function

This function is similar to the send() function, but three additional arguments are required.
The sendto() function is defined as follows:

#include <sys/socket.h>
ssize_t sendto(int sockfd, const void *buff, size_t nbytes,
int flags, const struct sockaddr *to,
socklen_t addrlen);

The first three arguments sockfd, buff, and nbytes, are identical to the first three arguments of recv. sockfd is
the socket descriptor, buff is the pointer to write from, and nbytes is number of bytes to write. In our examples
we will set all the values of the flags argument to 0. The to argument is a socket address structure containing
the protocol address (e.g., IP address and port number) of where the data is sent. addlen specified the size of
this socket.

The function returns the number of bytes written if it succeeds, -1 on error.

Concurrent Servers

There are two main classes of servers, iterative and concurrent. An iterative server iterates through each
client, handling it one at a time. A concurrent server handles multiple clients at the same time. The simplest
technique for a concurrent server is to call the fork function, creating one child process for each client. An
alternative technique is to use threads instead (i.e., light-weight processes). We do not consider this kind of
servers in this course.

The fork() function

The fork() function is the only way in Unix to create a new process. It is defined as follows:

#include <unist.h>

pid_t fork(void);

The function returns 0 if in child and the process ID of the child in parent; otherwise, -1 on error.

In fact, the function fork() is called once but returns twice. It returns once in the calling process (called the
parent) with the process ID of the newly created process (its child). It also returns in the child, with a return
value of 0. The return value tells whether the current process is the parent or the child.

Example

A typical concurrent server has the following structure:

Web Programming Page 101


WEB PROGRAMMING

pid_t pid;
int listenfd, connfd;
listenfd = socket(...);

/***fill the socket address with server’s well known port***/

bind(listenfd, ...);
listen(listenfd, ...);

for ( ; ; ) {

connfd = accept(listenfd, ...); /* blocking call */

if ( (pid = fork()) == 0 ) {

close(listenfd); /* child closes listening socket */

/***process the request doing something using connfd ***/


/*...................*/

close(connfd);
exit(0); /* child terminates
}
close(connfd); /*parent closes connected socket*/
}
}

When a connection is established, accept returns, the server calls fork, and the child process services the client
(on the connected socket connfd). The parent process waits for another connection (on the listening
socket listenfd. The parent closes the connected socket since the child handles the new client. The interactions
among client and server are presented in Figure 5.

Web Programming Page 102


WEB PROGRAMMING

Figure 5: Example of interaction among a client and a concurrent server.

TCP Client/Server Examples

We now present a complete example of the implementation of a TCP based echo server to summarize the
concepts presented above. We present an iterative and a concurrent implementation of the server.

echoClient.c source: echoClient.c

Web Programming Page 103


WEB PROGRAMMING

TCP Echo Client

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

#define MAXLINE 4096 /*max text line length*/


#define SERV_PORT 3000 /*port*/

int
main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr;
char sendline[MAXLINE], recvline[MAXLINE];

//basic check of the arguments


//additional checks can be inserted
if (argc !=2) {
perror("Usage: TCPClient <IP address of the server");
exit(1);
}

//Create a socket for the client


//If sockfd<0 there was an error in the creation of the socket
if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) <0)
{ perror("Problem in creating the socket");
exit(2);
}

//Creation of the socket


memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr= inet_addr(argv[1]);
servaddr.sin_port = htons(SERV_PORT); //convert to big-endian order

//Connection of the client to the socket


if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr))<0)
{ perror("Problem in connecting to the server");
exit(3);
}

while (fgets(sendline, MAXLINE, stdin) != NULL) {

send(sockfd, sendline, strlen(sendline), 0);

if (recv(sockfd, recvline, MAXLINE,0) == 0){


Web Programming Page 104
WEB PROGRAMMING

//error: server terminated prematurely


perror("The server terminated prematurely");
exit(4);
}
printf("%s", "String received from the server: ");
fputs(recvline, stdout);
}

exit(0);
}

echoServer.c source: echoServer.c

TCP Iterative Server

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

#define MAXLINE 4096 /*max text line length*/


#define SERV_PORT 3000 /*port*/
#define LISTENQ 8 /*maximum number of client connections */

int main (int argc, char **argv)


{
int listenfd, connfd, n;
socklen_t clilen;
char buf[MAXLINE];
struct sockaddr_in cliaddr, servaddr;

//creation of the socket


listenfd = socket (AF_INET, SOCK_STREAM, 0);

//preparation of the socket address


servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);

bind (listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));

listen (listenfd, LISTENQ);

printf("%s\n","Server running...waiting for connections.");

for ( ; ; ) {

clilen = sizeof(cliaddr);
Web Programming Page 105
WEB PROGRAMMING

connfd = accept (listenfd, (struct sockaddr *) &cliaddr, &clilen); printf("%s\


n","Received request...");

while ( (n = recv(connfd, buf, MAXLINE,0)) > 0)


{ printf("%s","String received from and resent to the
client:"); puts(buf);
send(connfd, buf, n, 0);
}

if (n < 0)
{ perror("Read
error"); exit(1);
}
close(connfd);

}
//close listening socket
close (listenfd);
}

conEchoServer.c source: conEchoServer.c

TCP Concurrent Echo Server

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

#define MAXLINE 4096 /*max text line length*/


#define SERV_PORT 3000 /*port*/
#define LISTENQ 8 /*maximum number of client connections*/

int main (int argc, char **argv)


{
int listenfd, connfd, n;
pid_t childpid;
socklen_t clilen;
char buf[MAXLINE];
struct sockaddr_in cliaddr, servaddr;

//Create a socket for the soclet


//If sockfd<0 there was an error in the creation of the socket
if ((listenfd = socket (AF_INET, SOCK_STREAM, 0)) <0) {
perror("Problem in creating the socket");
exit(2);
}

Web Programming Page 106


WEB PROGRAMMING

//preparation of the socket address


servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);

//bind the socket


bind (listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));

//listen to the socket by creating a connection queue, then wait for clients
listen (listenfd, LISTENQ);

printf("%s\n","Server running...waiting for connections.");

or ( ; ; ) {

clilen = sizeof(cliaddr);
//accept a connection
connfd = accept (listenfd, (struct sockaddr *) &cliaddr, &clilen);

printf("%s\n","Received request...");

if ( (childpid = fork ()) == 0 ) {//if it’s 0, it’s child process

printf ("%s\n","Child created for dealing with client requests");

//close listening socket


close (listenfd);

while ( (n = recv(connfd, buf, MAXLINE,0)) > 0)


{ printf("%s","String received from and resent to the
client:"); puts(buf);
send(connfd, buf, n, 0);
}

if (n < 0)
printf("%s\n", "Read error");
exit(0);
}
//close socket of the server
close(connfd);
}
}

Java RMI

RMI stands for Remote Method Invocation. It is a mechanism that allows an object residing
in one system (JVM) to access/invoke an object running on another JVM.

Web Programming Page 107


WEB PROGRAMMING

RMI is used to build distributed applications; it provides remote communication


between Java programs. It is provided in the package java.rmi.

Architecture of an RMI Application


In an RMI application, we write two programs, a server program (resides on the
server) and a client program (resides on the client).
 Inside the server program, a remote object is created and reference of that
object is made available for the client (using the registry).
 The client program requests the remote objects on the server and tries to invoke
its methods. The following diagram shows the architecture of an RMI application.

Let us now discuss the components of this architecture.


 Transport Layer − This layer connects the client and the server. It manages the
existing connection and also sets up new connections.
 Stub − A stub is a representation (proxy) of the remote object at client. It resides
in the client system; it acts as a gateway for the client program.
 Skeleton − This is the object which resides on the server side. stub communicates
with this skeleton to pass request to the remote object.
 RRL(Remote Reference Layer) − It is the layer which manages the references made
by the client to the remote object.
Working of an RMI Application
The following points summarize how an RMI application works −
 When the client makes a call to the remote object, it is received by the stub which
eventually passes this request to the RRL.
 When the client-side RRL receives the request, it invokes a method called
invoke() of the object remoteRef. It passes the request to the RRL on the server
side.
Web Programming Page 108
WEB PROGRAMMING
 The RRL on the server side passes the request to the Skeleton (proxy on the
server) which finally invokes the required object on the server.

Web Programming Page 109


WEB PROGRAMMING

 The result is passed all the way back to the client.


Marshalling and Unmarshalling
Whenever a client invokes a method that accepts parameters on a remote object, the
parameters are bundled into a message before being sent over the network. These
parameters may be of primitive type or objects. In case of primitive type, the
parameters are put together and a header is attached to it. In case the parameters are
objects, then they are serialized. This process is known as marshalling.
At the server side, the packed parameters are unbundled and then the required method
is invoked. This process is known as unmarshalling.

RMI Registry
RMI registry is a namespace on which all server objects are placed. Each time the
server creates an object, it registers this object with the RMIregistry (using bind() or
reBind() methods). These are registered using a unique name known as bind name.
To invoke a remote object, the client needs a reference of that object. At that time, the
client fetches the object from the registry using its bind name (using lookup() method).
The following illustration explains the entire process −

Goals of RMI
Following are the goals of RMI −

 To minimize the complexity of the application.


 To preserve type safety.

Web Programming Page 110


WEB PROGRAMMING
 Distributed garbage collection.

Web Programming Page 111


WEB PROGRAMMING

Minimize the difference between working with loca

Web Programming Page 112

You might also like