I / O Multiplexing Model :
IN this select or poll functions are called instead of recvfrom. The summary of I/O Multiplexing call is given in the following figure:
IN this
the call to select is blocked waiting for the datagram socket to be readable.
When select returns that the socket is readable, then the recvfrom called to
copy the datagram into the application.
Compared
to blocking model, the difference here is that the application can wait for
more than one descriptors to be ready. The disadvantages is that select
requires two system calls.
Signal Driven I/O Model
Signals
are used to tell the kernel to notify applications with the SIGIO signal when the descriptor is
ready. It is called signal driven I/O
Model. The summary is shown in the following figure.
First enable the socket for the signal driven
I/O and install a signal handler using the sigaction
system call. The return from this system call is immediate and our process
continuous, it is not block. When the datagram is ready to be ready, the SIGIO
signal is generated for our process. We can either read the datagram from the
signal handler by calling recvfrom and then notify the main loop that the data
is ready to be process, or we can notify the main lop and let it read the
datagram.
The advantage I this model is that we are not
blocked while waiting for the datagram top arrive. The main loop can continue
executing and just wait to be notified by the signal handler that either the
dta is read to process or that the datagram is ready to be read.
Asynchronous I/O Model
Asynchronous
I/O are new with the 1993 edition of Posix 1g. In this the kernel is told to
start operation and to notify when the entire operation (including the copy of
the data from the kernel to our buffer ) is over.
The main difference between this and the signal driven I/O model in the previous section is that with the signal driven I/O the kernel tells when the I/O operation can be initiated. But with asynchronous I/O, the kernel tells us when an I/O operation is complete. It is summarized as given below:
The
function aio_read is called and the
descriptor, buffer pointer, buffer size, file offset and how to notify when the
entire operation is complete are passed to the kernel. The system calls returns
immediately and our process is not blocked waiting for the I./O to complete. It
is expected that the kernel will generate some signal when the operation is
complete. The signal is generated only when the data is copied completely in
the application buffer.
Comparison
of the I/O Model
The main
difference between the four models is the first phase as the second phase in
the first four models is the same. The process is blocked in a cal to recvfrom while the data is copied from
the kernel to the caller‘s buffer. Asynchronous I/O however, handles both the
phases and is different form the first four.
Synchronous vs asynchronous:
A
synchronous I/O operation causes the requesting process to be blocked until
that I?O operation is completes.
An asynchronous I/O operation does not cause
the requesting process to be blocked.
Based on
this definition, the first four are synchronous as the actual I/O operation
blocks the process. Only asynchronous I/O model matches the asynchronous I/O
definition.
Select Function :
The
select function allows the process to instruct the kernel to wait for any one
of the multiple events to occur and to wake up the process only when one or
more of these events occurs or when a specified amount of time has passed.
As an example, we can call select and tell the kernel to return only
•
any of
the descriptors in the set { 1,4,5} are ready for reading, or
•
any of
the descriptors in the set {2,7} are ready for writing, or
•
any of
the descriptors in the set {1,4 } have an exception condition pending or
•
after
10.2. seconds have elapsed.
That the kernel is told in what descriptors we
are interested in (for reading, writing or an exception condition) and how long
to wait. The descriptors in which we are interested are not restricted to
sockets: any descriptor can be tested using select.
#include <sys/select.h> #include
<sys/time.h>
int
select (int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *excepset, const
struct timeval *timeout); returns : positive count of ready descriptors, o on
timeout, -1 on error.
Consider
the final arguments: This tells the kernel how long to wait for one of the
specified descriptors to become ready. A timeval
structure specifies the number of seconds and microseconds.
Struct
timeval
long tv_sec; /*
seconds */
long tv_usec; /*
micros seconds */
}
There are three possibilities:
•
wait forever: return only when one of the specified descriptors is ready for
I/O . For this, we specify the
timeout argument as a null pointer.
•
Wait upto a fixed amount of time: return when one of the specified descriptors
is ready for I/O, but do not wait
beyond the number of seconds and microseconds specified in the timeval structure pointer to by the timeout argument.
•
Do not wait at all: return immediately after checking the
descriptors. This is called polling.
To specify this, the timeout
argument must point to a timeval structure and the timer value must be zero
In case of first two scenario, the wait is
normally interrupted if the process catches a signal and returns from the
signal handler.
The
const qualifier on the timeout argument means it is not modified by select on
return. For example, if we specify a time limit of 10 sec, and select returns
before the timer expires, with one or more descriptors ready or with an error
of EINTR, the timeval structure is not updated with the number of seconds
remaining when the functions returns.
The
three middle arguments readset, writeset and excepset specify the descriptors
that we want the kernel to test for
reading, writing and exception conditions.
The two exceptions conditions currently
supported are:
•
The
arrival of out of bound data for a socket.
•
The
control status information to be read from the master side of pseudo terminal
The maxfdp1
argument specifies the number of descriptors to be tested. Its value is the
maximum descriptors to be tested plus one. The descriptors 0,1,2, through and
including maxfdp1 –1 are tested. The
constant FD_SETSIZE defined by including <sys /select.h>, is the number
of descriptors in the fd_set
data type. It s value is often 1024, but few
programs use that many descriptors. The maxfdp1
argument forces us to calculate the largest descriptors that we are interested
in and then tell the kernel this value. For 1,4,5 the maxfdp1 is 6.
The design problem is how to specify one or
more descriptors values for each of these three arguments. Select uses descriptor sets,
typically an array of integers – a32 by 32 array- of 1024 descriptors
set. The descriptors are programmed for initializing /reading / writing and for
closing using the following macros:
void FD_ZERO (fd_set * fset) /*
clear all bits in fset */
void FD_SET (int fd, fd_set * fset) /* Turn on the bit for fd in fset*/
void FD_CLR (int fd, fd_set * fset) /*turn off the bit for fd in fset
void FD_ISSET (int fd, fd_set
* fset) /* is the bit for fd
on in fset? */
For example to define a variable of type fd_set
and then turn on the bits for descriptors, we write
fd_set rset;
FD_ZERO (&rset); /* initialize the set;
all bits to zet */
FD_SET (1, &rset); /* turn on bit for fd 1
FD_SET (4, &rset ); /* turn on bit for fd
4; */
If the descriptors are initialized to zero,
unexpected results are likely to come.
Middle arguments to select, readset, writeset,
or exceptset can be specified as null pointer, if we are not interest in that
condition. The maxfdp1 arguments specifies the number of descriptors to be
tested. Its value is the maximum descriptors to be tested, plus one (hence the
name maxfdp1). The descriptors 0,1,2 up through and including maxfdp1 – 1 are
tested.
Select function modifies the descriptor sets
pointed by the readset, writset and excepset pointers. These three arguments
are value-result arguments. When we call the function, we specify the values of
the descriptors that we are interested in and on return the result indicates
which descriptors are ready. We use FD_ISSET macros return to test a specific
descriptor in an fd_set structure. Any descriptors that is not ready on return
will have its corresponding bit cleared in the descriptors set.
str_cli Function :
The str_cli Function is rewritten using the
select function as shown below:
# include ―unp.h‖
void str_cli (FILE *fp, int socket)
{
int maxfdp1;
fd_set rset;
char sendline[MAXLINE], recvline[MAXLINE];
FD_ZERO (&rset);
for ( ; ;)
{
FD_SET (fileno (fp), &rset);
FD_SET (sockfd, &rset);
maxfdp1 = max (fileno (fp), sockfd) + 1;
select (maxfdp1, &rset, NULL, NULL, NULL);
if (FD_ISSET(sockfd, &rset))
{ if
(readline (sockfd, recvline, MAXLINE)==0)
err_quit (―str_cli: server terminated
prematurely‖); fputs (recvline, stdout);
}
if (FD_ISSET(fileno(fp), &rset))
{if (fgets (sendline, MAXLINE, fp)==NULL)
return;
writen(sockfd, sendline, strlen (sendline));
}
}
}
IN the above code the descriptors set is
initialized to zero using FD_ZERO. Then, the descriptors, file pointer fp and socket sockfd are turned on using FD_SET. maxfdp1 is calculated from the
descriptors list. Select function is
called. IN this writeset pointer and exception set pointers are both NULL.
Final time pointer is also NULL as the call is to be blocked until something is
ready.
If on
return from the select, socket is readable, the echoed line is read with readline and output by fputs.
If the standard input is readable, a line is
read by fget sand written to the
sockets using writen.
IN this although the four functions fgets,
writen, readline and fputs are used, the order of flow within the function has
changed. In this, instead of flow being driven by the call to fgets, it is
driven by the call to select.
This has enhanced the robustness of the client.
Batch
Input:
The echo client server, works in a stop and
wait mode. That is , it sends a line to the server and then waits for the reply.
This amount of time is one RTT (Round Trip Time) plus the server‘s processing
time. If we consider the network between the client and the server as a full
duplex pipe with requests from the client to server, and replies in the reverse
direction, then the following shows the stop and wait mode.
The
request is sent by the client at time 0 and we assume RTT of 8 units of time.
The reply sent at a time 4 is received at time 7. It is assumed that there is
no serving processing time and that the size of the request is the same as the
reply. Also, TCP acknowledgment are ignored.
But as
there is a delay between sending a packet and that packet arriving at the other end of the pipe,
and since the pipe is full duplex, in this
example we are only using one- eighth of the pipe capacity.
This stop and wait mode is fine for interactive
input, but since our client reads from standard input and writes to standard
output, we can easily run our client in a batch mode. When the input is
redirected as in client server example, the output file is always same.
To see what is happening in the batch mode, we
can keep sending requests as fast as the network can accept them. The server
processes them and sends back the replies at the same rate. This leads to the
full pipe at time 7 as shown below:
Filling the pipe between the client and the
sever : batch Mode;
Now to
understand the problem with the str_cli,
let the input file contains only nine lines. The last line is sent at time 8 as
shown above. But we cannot close the connection after writing this request,
because there are still other requests and rep0les in the pipe. The cause of
the problem is our handling of end of file on input. The function returns to
the main function, which then terminates. But in a batch mode, an end of file
on the input does not imply. That we have finished reading from the socket.
There might still requests on the way to the server or replies on the way to
back from the server.
What we
need is a way to close one half of the TCP connection. That is we want to send
FIN to the server, telling it we have finished sending data, but leave the
socket descriptors for reading. This is done with the shutdown function.
Related Topics
Privacy Policy, Terms and Conditions, DMCA Policy and Compliant
Copyright © 2018-2023 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.