Wednesday, June 17, 2009

Transfer Control Protocol (TCP)

Posted by Sarjukottapuram

TRANSFER CONTROL PROTOCOL(TCP)


Server

Algorithm

The activity involved in a tcp server are..........
1.Create a socket.
2.Bind it to the operating system.
3.Listen over it.
4.Accept connections.
5.Read/Write processes.
6.Close the socket.

Program

/*Program to demonstrate the creation and usage of tcp socket.
* This module acts as the tcp server which listens to a socket and accepts connection.
* The server initially reads a message from the client and then writes a message to it.
* This module should be compiled using the command. 'c++ tcpserver.cpp' and execute './a.out'.*/

//inculsion.
#include
#include
#include
#include
#include
int main()
{

//variables to store the socket id.
int serversocket,clientsocket;

//variables to store the network host addresses.
sockaddr_in serveraddr,clientaddr;

//variable to store address length.
socklen_t len;
char message[50];

//creating a socket.
serversocket=socket(AF_INET,SOCK_STREAM,0);

//steps to include the host address
bzero((char*)&serveraddr,sizeof(serveraddr));
serveraddr.sin_family=AF_INET;
serveraddr.sin_port=htons(5030);
serveraddr.sin_addr.s_addr=INADDR_ANY;

//binding the socket to the operating system.
bind(serversocket,(sockaddr*)&serveraddr,sizeof(serveraddr));
bzero((char*)&clientaddr,sizeof(clientaddr));
len=sizeof(clientaddr);

//listening over the socket.
listen(serversocket,5);
printf("\nWaiting for client connectivity.\n");

//accepting the connection.
clientsocket=accept(serversocket,(sockaddr*)&clientaddr,&len);
printf("\nClient connectivity received.\n");
printf("\nReading message from the client.\n");

//reading activity.
read(clientsocket,message,sizeof(message));
printf("\nThe client has send:\t%s\n",message);
printf("\nSending message to the client.\n");

//writing activity.
write(clientsocket,"YOUR MESSAGE RECEIVED.",sizeof("YOUR MESSAGE RECEIVED."));
close(clientsocket);
close(serversocket);
}
Output

Client

Algorithm

The different processes involved in a udp client process are........
1.Create a datagram socket.
2.Receive/Send message to the server.
3.Close the socket.

Program
/* Program to demonstrate the creation and usage of datagram sockets.
* This module acts as a udp client which sends and receives messages from a udp server.
* This module should be compiled into different folder using the command 'c++
udpclient.cpp -o b' and execute using './b'
* For execution the 'udpserver' module should be executed first then this module.

//inculsion.
#include
#include
#include
#include
#include
int main()
{

//variable to store the socket_id.
int clientsocket;

//variable to store the address.
sockaddr_in serveraddr;

//variableto store the address length.
socklen_t len;

//variable to store the network byte order address.
hostent *server;
char message[50];

//socket creation.
clientsocket=socket(AF_INET,SOCK_DGRAM,0);

//steps involved in the server address creation.
bzero((char*)&serveraddr,sizeof(serveraddr));
len=sizeof(serveraddr);
serveraddr.sin_family=AF_INET;
serveraddr.sin_port=htons(5015);
server=gethostbyname("127.0.0.1");
bcopy((char*)server->h_addr,(char*)&serveraddr.sin_addr.s_addr,sizeof(server->h_addr));
printf("\nPRESS ENTER TO START THE CONNECTION PROCESS.\n");
fgets(message,2,stdin);
printf("\nSending message for server connection\n");

//sending message.
sendto(clientsocket,"HI I AM CLIENT...",sizeof("HI I AM CLIENT...."),0,(sockaddr*)&serveraddr,sizeof(serveraddr));
printf("\nReceiving message from server.\n");

//receiving messages.
recvfrom(clientsocket,message,sizeof(message),0,(sockaddr*)&serveraddr,&len);
printf("\nMessage received:\t%s\n",message);
close(clientsocket);
}

Output

Socket Programming

Posted by Sarjukottapuram

SOCKET PROGRAMMING

Theory

Sockets provide point-to-point, two-way communication between two processes. Sockets are very versatile and are a basic component of interprocess and intersystem communication. A socket is an endpoint of communication to which a name can be bound. It has a type and one or more associated processes.
Sockets exist in communication domains. A socket domain is an abstraction that provides an addressing structure and a set of protocols. Sockets connect only with sockets in the same domain. Twenty three socket domains are identified (see ), of which only the UNIX and Internet domains are normally used Solaris 2.x Sockets can be used to communicate between processes on a single system, like other forms of IPC.
The UNIX domain provides a socket address space on a single system. UNIX domain sockets are named with UNIX paths. Sockets can also be used to communicate between processes on different systems. The socket address space between connected systems is called the Internet domain.
Internet domain communication uses the TCP/IP internet protocol suite.
Socket types define the communication properties visible to the application. Processes communicate only between sockets of the same type. There are five types of socket.
A stream socket
-- provides two-way, sequenced, reliable, and unduplicated flow of data with no record boundaries. A stream operates much like a telephone conversation. The socket type is SOCK_STREAM, which, in the Internet domain, uses Transmission Control Protocol (TCP).

A datagram socket
-- supports a two-way flow of messages. A on a datagram socket may receive messages in a different order from the sequence in which the messages were sent. Record boundaries in the data are preserved. Datagram sockets operate much like passing letters back and forth in the mail. The socket type is SOCK_DGRAM, which, in the Internet domain, uses User Datagram Protocol (UDP).
A sequential packet socket
-- provides a two-way, sequenced, reliable, connection, for datagrams of a fixed maximum length. The socket type is SOCK_SEQPACKET. No protocol for this type has been implemented for any protocol family.
A raw socket
provides access to the underlying communication protocols.

These sockets are usually datagram oriented, but their exact characteristics depend on the interface provided by the protocol.

Socket Creation and Naming

int socket(int domain, int type, int protocol) is called to create a socket in the specified domain and of the specified type. If a protocol is not specified, the system defaults to a protocol that supports the specified socket type. The socket handle (a descriptor) is returned. A remote process has no way to identify a socket until an address is bound to it. Communicating processes connect through addresses. In the UNIX domain, a connection is usually composed of one or two path names. In the Internet domain, a connection is composed of local and remote addresses and local and remote ports. In most domains, connections must be unique.
int bind(int s, const struct sockaddr *name, int namelen) is called to bind a path or internet address to a socket. There are three different ways to call bind(), depending on the domain of the socket.

• For UNIX domain sockets with paths containing 14, or fewer characters, you can:
• #include
• ...
• bind (sd, (struct sockaddr *) &addr, length);
• If the path of a UNIX domain socket requires more characters, use:
• #include
• ...
• bind (sd, (struct sockaddr_un *) &addr, length);
• For Internet domain sockets, use
• #include
• ...
• bind (sd, (struct sockaddr_in *) &addr, length);
In the UNIX domain, binding a name creates a named socket in the file system. Use unlink() or rm () to remove the socket.

Connecting Stream Sockets

Connecting sockets is usually not symmetric. One process usually acts as a server and the other process is the client. The server binds its socket to a previously agreed path or address. It then blocks on the socket. For a SOCK_STREAM socket, the server calls int listen(int s, int backlog) , which specifies how many connection requests can be queued. A client initiates a connection to the server's socket by a call to int connect(int s, struct sockaddr *name, int namelen) . A UNIX domain call is like this:
struct sockaddr_un server;
...
connect (sd, (struct sockaddr_un *)&server, length);
while an Internet domain call would be:
struct sockaddr_in;
...
connect (sd, (struct sockaddr_in *)&server, length);
If the client's socket is unbound at the time of the connect call, the system automatically selects and binds a name to the socket. For a SOCK_STREAM socket, the server calls accept(3N) to complete the connection.
int accept(int s, struct sockaddr *addr, int *addrlen) returns a new socket descriptor which is valid only for the particular connection. A server can have multiple SOCK_STREAM connections active at one time.
Stream Data Transfer and Closing

Several functions to send and receive data from a SOCK_STREAM socket. These are write(), read(), int send(int s, const char *msg, int len, int flags), and int recv(int s, char *buf, int len, int flags). send() and recv() are very similar to read() and write(), but have some additional operational flags.

The flags parameter is formed from the bitwise OR of zero or more of the following:

MSG_OOB
-- Send "out-of-band" data on sockets that support this notion. The underlying protocol must also support "out-of-band" data. Only SOCK_STREAM sockets created in the AF_INET address family support out-of-band data.

MSG_DONTROUTE
-- The SO_DONTROUTE option is turned on for the duration of the operation. It is used only by diagnostic or routing pro- grams.

MSG_PEEK
-- "Peek" at the data present on the socket; the data is returned, but not consumed, so that a subsequent receive operation will see the same data.

A SOCK_STREAM socket is discarded by calling close().

Datagram sockets

A datagram socket does not require that a connection be established. Each message carries the destination address. If a particular local address is needed, a call to bind() must precede any data transfer. Data is sent through calls to sendto() or sendmsg(). The sendto() call is like a send() call with the destination address also specified. To receive datagram socket messages, call recvfrom() or recvmsg(). While recv() requires one buffer for the arriving data, recvfrom() requires two buffers, one for the incoming message and another to receive the source address.
Datagram sockets can also use connect() to connect the socket to a specified destination socket. When this is done, send() and recv() are used to send and receive data.

accept() and listen() are not used with datagram sockets.

Shared Memory

Posted by Sarjukottapuram

SHARED MEMORY

Theory

In computing, shared memory is a memory that may be simultaneously accessed by multiple programs with an intent to provide communication among them. Depending on context, programs may run on the same physical processor or on separate ones. Using memory for communication inside a single program, for example among its multiple threads, is generally not referred to as shared memory.
In computer software, shared memory is a method of inter-process communication (IPC), i.e. a way of exchanging data between programs running at the same time. One process will create an area in RAM which other processes can access.
Since both processes can access the shared memory area like regular working memory, this is a very fast way of communication (as opposed to other mechanisms of IPC such as named pipes, Unix sockets or CORBA). On the other hand, it is less powerful, as for example the communicating processes must be running on the same machine (whereas other IPC methods can use a computer network).
IPC by shared memory is mainly used on Unix systems.
POSIX provides a standardized API for using shared memory, POSIX Shared Memory. This uses the function shm_open from sys/mman.h.
Shared Memory is an efficeint means of passing data between programs. One program will create a memory portion which other processes (if permitted) can access.
In the Solaris 2.x operating system, the most efficient way to implement shared memory applications is to rely on the mmap() function and on the system's native virtual memory facility. Solaris 2.x also supports System V shared memory, which is another way to let multiple processes attach a segment of physical memory to their virtual address spaces. When write access is allowed for more than one process, an outside protocol or mechanism such as a semaphore can be used to prevent inconsistencies and collisions.
A process creates a shared memory segment using shmget()|. The original owner of a shared memory segment can assign ownership to another user with shmctl(). It can also revoke this assignment. Other processes with proper permission can perform various control functions on the shared memory segment using shmctl(). Once created, a shared segment can be attached to a process address space using shmat(). It can be detached using shmdt() (see shmop()). The attaching process must have the appropriate permissions for shmat(). Once attached, the process can read or write to the segment, as allowed by the permission requested in the attach operation. A shared segment can be attached multiple times by the same process. A shared memory segment is described by a control structure with a unique ID that points to an area of physical memory. The identifier of the segment is called the shmid. The structure definition for the shared memory segment control structures and prototypews can be found in .
Accessing a Shared Memory Segment
shmget() is used to obtain access to a shared memory segment. It is prottyped by:
int shmget(key_t key, size_t size, int shmflg);
The key argument is a access value associated with the semaphore ID. The size argument is the size in bytes of the requested shared memory. The shmflg argument specifies the initial access permissions and creation control flags.
When the call succeeds, it returns the shared memory segment ID. This call is also used to get the ID of an existing shared segment (from a process requesting sharing of some existing memory portion).
The following code illustrates shmget():

#include
#include
#include
...
key_t key; /* key to be passed to shmget() */
int shmflg; /* shmflg to be passed to shmget() */
int shmid; /* return value from shmget() */
int size; /* size to be passed to shmget() */
...
key = ...
size = ...
shmflg) = ...

if ((shmid = shmget (key, size, shmflg)) == -1) {
perror("shmget: shmget failed"); exit(1); } else {
(void) fprintf(stderr, "shmget: shmget returned %d\n", shmid);
exit(0);
}
...

Controlling a Shared Memory Segment

shmctl() is used to alter the permissions and other characteristics of a shared memory segment. It is prototyped as follows:
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
The process must have an effective shmid of owner, creator or superuser to perform this command. The cmd argument is one of following control commands:
SHM_LOCK -- Lock the specified shared memory segment in memory. The process must have the effective ID of superuser to perform this command.
SHM_UNLOCK -- Unlock the shared memory segment. The process must have the effective ID of superuser to perform this command.
IPC_STAT-- Return the status information contained in the control structure and place it in the buffer pointed to by buf. The process must have read permission on the segment to perform this command.
IPC_SET-- Set the effective user and group identification and access permissions. The process must have an effective ID of owner, creator or superuser to perform this command.
IPC_RMID -- Remove the shared memory segment.
The buf is a sructure of type struct shmid_ds which is defined in

Program
Server

/*Program to demonstrate the use of shared memory in interprocess communication.
* This program acts as a server which waits for a message from the client process.
* The process is implemented using a shared memory space called 'shared_location'.
* The 'message' part of this space stores the message while the 'written' part is used to indicate whether the server has read the message or the client has written the message.(0->read,1->written).
* This module should be compiled and executed first.
* This module is compile using 'cc shmserver.c' and executed using './a.out'*/

//inculsion
#include
#include
#include
#include
#include
#include

//structure definition for acquiring a shared location.
struct shared_location
{
int written;
char message[30];
};
int main()
{
int shmid,running;
void *address;
struct shared_location * ptr;

//for getting a shared location
shmid=shmget((key_t)1234,sizeof(struct shared_location),0666|IPC_CREAT);

//optional if required for error checking.
if(shmid<=0) { printf("\nERROR:\tCannot allocate shared space.\n"); exit(0); } //attaching the shared location to this process.
address=shmat(shmid,(void *)0,0); //optional if required for error checking.
if(address==(void*)0) { printf("\nEROOR:\tShared location cannot be attached.\n"); } //type casting so as to convert the obyained location into our format.
ptr=(struct shared_location*)address; ptr->written=0;
strcpy(ptr->message,"Hi I am server.");
running=1;
while(running)
{
printf("\nWaiting for the client to enter the message.\n");

while(ptr->written==0)
{
}
if(ptr->written==1)
{
printf("The client has entered the message: %s\n",ptr->message);
}
ptr->written=0;
if(strcmp(ptr->message,"end")==0)
{
running=0;
}
}

//detaching the shared location.
shmdt(address);

//deleting the shared location.
shmctl(shmid,IPC_RMID,NULL);
}

Output

Client

Program

/* Program to demonstrate the use of shared memory in interprocess communication.
* This module acts as a client which sends messages to the server process.
* In this the message entered into the message part of the 'shared_location' structure and the 'written' field is set to 1.
* The remaining process is similar to that of the server process.
* This module can be compiled using 'cc shmclient.c -o b' and executed using './b'

//inculsion
#include
#include
#include
#include
#include
#include

//structure definition for the shared location.
struct shared_location
{
int written;
char message[30];
};

//the functions and other terms used have similar meanings to that used in the server module
 //but they don't bear any specific relationship.
int main()
{
int shmid,running;
void *address;
struct shared_location * ptr;
shmid=shmget((key_t)1234,sizeof(struct shared_location),0666|IPC_CREAT);
if(shmid<=0)
{
printf("\nERROR:\tCannot allocate shared memory.\n");
exit(0);
}
address=shmat(shmid,(void*)0,0);
if(address==(void*)0)
{
printf("\nERROR:\tCannot attach the shared location\n");
exit(0);
}
ptr=(struct shared_location*)address;
running=1;
while(running)
{
printf("\nWaiting for the server\n");
while(ptr->written==1)
{
}
printf("\nEnter your message.(type 'end' to exit)\n");
scanf("%s",ptr->message);
ptr->written=1;
if(strcmp(ptr->message,"end")==0)
{
running=0;
}
}
address=shmat(shmid,(void *)0,0);
shmdt(address);
}

Output