”;
What is a Socket?
Sockets allow communication between two different processes on the same or different machines. To be more precise, it”s a way to talk to other computers using standard Unix file descriptors. In Unix, every I/O action is done by writing or reading a file descriptor. A file descriptor is just an integer associated with an open file and it can be a network connection, a text file, a terminal, or something else.
To a programmer, a socket looks and behaves much like a low-level file descriptor. This is because commands such as read() and write() work with sockets in the same way they do with files and pipes.
Sockets were first introduced in 2.1BSD and subsequently refined into their current form with 4.2BSD. The sockets feature is now available with most current UNIX system releases.
Where is Socket Used?
A Unix Socket is used in a client-server application framework. A server is a process that performs some functions on request from a client. Most of the application-level protocols like FTP, SMTP, and POP3 make use of sockets to establish connection between client and server and then for exchanging data.
Socket Types
There are four types of sockets available to the users. The first two are most commonly used and the last two are rarely used.
Processes are presumed to communicate only between sockets of the same type but there is no restriction that prevents communication between sockets of different types.
-
Stream Sockets − Delivery in a networked environment is guaranteed. If you send through the stream socket three items “A, B, C”, they will arrive in the same order − “A, B, C”. These sockets use TCP (Transmission Control Protocol) for data transmission. If delivery is impossible, the sender receives an error indicator. Data records do not have any boundaries.
-
Datagram Sockets − Delivery in a networked environment is not guaranteed. They”re connectionless because you don”t need to have an open connection as in Stream Sockets − you build a packet with the destination information and send it out. They use UDP (User Datagram Protocol).
-
Raw Sockets − These provide users access to the underlying communication protocols, which support socket abstractions. These sockets are normally datagram oriented, though their exact characteristics are dependent on the interface provided by the protocol. Raw sockets are not intended for the general user; they have been provided mainly for those interested in developing new communication protocols, or for gaining access to some of the more cryptic facilities of an existing protocol.
-
Sequenced Packet Sockets − They are similar to a stream socket, with the exception that record boundaries are preserved. This interface is provided only as a part of the Network Systems (NS) socket abstraction, and is very important in most serious NS applications. Sequenced-packet sockets allow the user to manipulate the Sequence Packet Protocol (SPP) or Internet Datagram Protocol (IDP) headers on a packet or a group of packets, either by writing a prototype header along with whatever data is to be sent, or by specifying a default header to be used with all outgoing data, and allows the user to receive the headers on incoming packets.
What is Next?
The next few chapters are meant to strengthen your basics and prepare a foundation before you can write Server and Client programs using socket. If you directly want to jump to see how to write a client and server program, then you can do so but it is not recommended. It is strongly recommended that you go step by step and complete these initial few chapters to make your base before moving on to do programming.
Unix Socket – Network Addresses
Before we proceed with the actual stuff, let us discuss a bit about the Network Addresses − the IP Address.
The IP host address, or more commonly just IP address, is used to identify hosts connected to the Internet. IP stands for Internet Protocol and refers to the Internet Layer of the overall network architecture of the Internet.
An IP address is a 32-bit quantity interpreted as four 8-bit numbers or octets. Each IP address uniquely identifies the participating user network, the host on the network, and the class of the user network.
An IP address is usually written in a dotted-decimal notation of the form N1.N2.N3.N4, where each Ni is a decimal number between 0 and 255 decimal (00 through FF hexadecimal).
Address Classes
IP addresses are managed and created by the Internet Assigned Numbers Authority (IANA). There are five different address classes. You can determine which class an IP address is in by examining the first four bits of the IP address.
-
Class A addresses begin with 0xxx, or 1 to 126 decimal.
-
Class B addresses begin with 10xx, or 128 to 191 decimal.
-
Class C addresses begin with 110x, or 192 to 223 decimal.
-
Class D addresses begin with 1110, or 224 to 239 decimal.
-
Class E addresses begin with 1111, or 240 to 254 decimal.
Addresses beginning with 01111111, or 127 decimal, are reserved for loopback and for internal testing on a local machine [You can test this: you should always be able to ping 127.0.0.1, which points to yourself]; Class D addresses are reserved for multicasting; Class E addresses are reserved for future use. They should not be used for host addresses.
Example
Class | Leftmost bits | Start address | Finish address |
A | 0xxx | 0.0.0.0 | 127.255.255.255 |
B | 10xx | 128.0.0.0 | 191.255.255.255 |
C | 110x | 192.0.0.0 | 223.255.255.255 |
D | 1110 | 224.0.0.0 | 239.255.255.255 |
E | 1111 | 240.0.0.0 | 255.255.255.255 |
Subnetting
Subnetting or subnetworking basically means to branch off a network. It can be done for a variety of reasons like network in an organization, use of different physical media (such as Ethernet, FDDI, WAN, etc.), preservation of address space, and security. The most common reason is to control network traffic.
The basic idea in subnetting is to partition the host identifier portion of the IP address into two parts −
- A subnet address within the network address itself; and
- A host address on the subnet.
For example, a common Class B address format is N1.N2.S.H, where N1.N2 identifies the Class B network, the 8-bit S field identifies the subnet, and the 8-bit H field identifies the host on the subnet.
Unix Socket – Network Host Names
Host names in terms of numbers are difficult to remember and hence they are termed by ordinary names such as Takshila or Nalanda. We write software applications to find out the dotted IP address corresponding to a given name.
The process of finding out dotted IP address based on the given alphanumeric host name is known as hostname resolution.
A hostname resolution is done by special software residing on high-capacity systems. These systems are called Domain Name Systems (DNS), which keep the mapping of IP addresses and the corresponding ordinary names.
The /etc/hosts File
The correspondence between host names and IP addresses is maintained in a file called hosts. On most of the systems, this file is found in /etc directory.
Entries in this file look like the following −
# This represents a comments in /etc/hosts file. 127.0.0.1 localhost 192.217.44.207 nalanda metro 153.110.31.18 netserve 153.110.31.19 mainserver centeral 153.110.31.20 samsonite 64.202.167.10 ns3.secureserver.net 64.202.167.97 ns4.secureserver.net 66.249.89.104 www.google.com 68.178.157.132 services.amrood.com
Note that more than one name may be associated with a given IP address. This file is used while converting from IP address to host name and vice versa.
You would not have access to edit this file, so if you want to put any host name along with IP address, then you would need to have root permission.
Unix Socket – Client Server Model
Most of the Net Applications use the Client-Server architecture, which refers to two processes or two applications that communicate with each other to exchange some information. One of the two processes acts as a client process, and another process acts as a server.
Client Process
This is the process, which typically makes a request for information. After getting the response, this process may terminate or may do some other processing.
Example, Internet Browser works as a client application, which sends a request to the Web Server to get one HTML webpage.
Server Process
This is the process which takes a request from the clients. After getting a request from the client, this process will perform the required processing, gather the requested information, and send it to the requestor client. Once done, it becomes ready to serve another client. Server processes are always alert and ready to serve incoming requests.
Example − Web Server keeps waiting for requests from Internet Browsers and as soon as it gets any request from a browser, it picks up a requested HTML page and sends it back to that Browser.
Note that the client needs to know the address of the server, but the server does not need to know the address or even the existence of the client prior to the connection being established. Once a connection is established, both sides can send and receive information.
2-tier and 3-tier architectures
There are two types of client-server architectures −
-
2-tier architecture − In this architecture, the client directly interacts with the server. This type of architecture may have some security holes and performance problems. Internet Explorer and Web Server work on two-tier architecture. Here security problems are resolved using Secure Socket Layer (SSL).
-
3-tier architectures − In this architecture, one more software sits in between the client and the server. This middle software is called ‘middleware’. Middleware are used to perform all the security checks and load balancing in case of heavy load. A middleware takes all requests from the client and after performing the required authentication, it passes that request to the server. Then the server does the required processing and sends the response back to the middleware and finally the middleware passes this response back to the client. If you want to implement a 3-tier architecture, then you can keep any middleware like Web Logic or WebSphere software in between your Web Server and Web Browser.
Types of Server
There are two types of servers you can have −
-
Iterative Server − This is the simplest form of server where a server process serves one client and after completing the first request, it takes request from another client. Meanwhile, another client keeps waiting.
-
Concurrent Servers − This type of server runs multiple concurrent processes to serve many requests at a time because one process may take longer and another client cannot wait for so long. The simplest way to write a concurrent server under Unix is to fork a child process to handle each client separately.
How to Make Client
The system calls for establishing a connection are somewhat different for the client and the server, but both involve the basic construct of a socket. Both the processes establish their own sockets.
The steps involved in establishing a socket on the client side are as follows −
-
Create a socket with the socket() system call.
-
Connect the socket to the address of the server using the connect() system call.
-
Send and receive data. There are a number of ways to do this, but the simplest way is to use the read() and write() system calls.
How to make a Server
The steps involved in establishing a socket on the server side are as follows −
-
Create a socket with the socket() system call.
-
Bind the socket to an address using the bind() system call. For a server socket on the Internet, an address consists of a port number on the host machine.
-
Listen for connections with the listen() system call.
-
Accept a connection with the accept() system call. This call typically blocks the connection until a client connects with the server.
-
Send and receive data using the read() and write() system calls.
Client and Server Interaction
Following is the diagram showing the complete Client and Server interaction −
Unix Socket – Structures
Various structures are used in Unix Socket Programming to hold information about the address and port, and other information. Most socket functions require a pointer to a socket address structure as an argument. Structures defined in this chapter are related to Internet Protocol Family.
sockaddr
The first structure is sockaddr that holds the socket information −
struct sockaddr { unsigned short sa_family; char sa_data[14]; };
This is a generic socket address structure, which will be passed in most of the socket function calls. The following table provides a description of the member fields −
Attribute | Values | Description |
---|---|---|
sa_family |
AF_INET AF_UNIX AF_NS AF_IMPLINK |
It represents an address family. In most of the Internet-based applications, we use AF_INET. |
sa_data | Protocol-specific Address | The content of the 14 bytes of protocol specific address are interpreted according to the type of address. For the Internet family, we will use port number IP address, which is represented by sockaddr_in structure defined below. |
sockaddr in
The second structure that helps you to reference to the socket”s elements is as follows −
struct sockaddr_in { short int sin_family; unsigned short int sin_port; struct in_addr sin_addr; unsigned char sin_zero[8]; };
Here is the description of the member fields −
Attribute | Values | Description |
---|---|---|
sa_family |
AF_INET AF_UNIX AF_NS AF_IMPLINK |
It represents an address family. In most of the Internet-based applications, we use AF_INET. |
sin_port | Service Port | A 16-bit port number in Network Byte Order. |
sin_addr | IP Address | A 32-bit IP address in Network Byte Order. |
sin_zero | Not Used | You just set this value to NULL as this is not being used. |
in addr
This structure is used only in the above structure as a structure field and holds 32 bit netid/hostid.
struct in_addr { unsigned long s_addr; };
Here is the description of the member fields −
Attribute | Values | Description |
---|---|---|
s_addr | service port | A 32-bit IP address in Network Byte Order. |
hostent
This structure is used to keep information related to host.
struct hostent { char *h_name; char **h_aliases; int h_addrtype; int h_length; char **h_addr_list #define h_addr h_addr_list[0] };
Here is the description of the member fields −
Attribute | Values | Description |
---|---|---|
h_name | ti.com etc. | It is the official name of the host. For example, tutorialspoint.com, google.com, etc. |
h_aliases | TI | It holds a list of host name aliases. |
h_addrtype | AF_INET | It contains the address family and in case of Internet based application, it will always be AF_INET. |
h_length | 4 | It holds the length of the IP address, which is 4 for Internet Address. |
h_addr_list | in_addr | For Internet addresses, the array of pointers h_addr_list[0], h_addr_list[1], and so on, are points to structure in_addr. |
NOTE − h_addr is defined as h_addr_list[0] to keep backward compatibility.
servent
This particular structure is used to keep information related to service and associated ports.
struct servent { char *s_name; char **s_aliases; int s_port; char *s_proto; };
Here is the description of the member fields −
Attribute | Values | Description |
---|---|---|
s_name | http | This is the official name of the service. For example, SMTP, FTP POP3, etc. |
s_aliases | ALIAS | It holds the list of service aliases. Most of the time this will be set to NULL. |
s_port | 80 | It will have associated port number. For example, for HTTP, this will be 80. |
s_proto |
TCP UDP |
It is set to the protocol used. Internet services are provided using either TCP or UDP. |
Tips on Socket Structures
Socket address structures are an integral part of every network program. We allocate them, fill them in, and pass pointers to them to various socket functions. Sometimes we pass a pointer to one of these structures to a socket function and it fills in the contents.
We always pass these structures by reference (i.e., we pass a pointer to the structure, not the structure itself), and we always pass the size of the structure as another argument.
When a socket function fills in a structure, the length is also passed by reference, so that its value can be updated by the function. We call these value-result arguments.
Always, set the structure variables to NULL (i.e., ”