Say “Hello World” with Socket Programming in “C”

Emorphis - Socket Programming in C

Network programming plays a vital part in development of peer-to-peer transmission of any kind message in any form. Whenever there is a need to  communicate between client and the server, socket programming plays an important role.

In this piece of writing, we are going to discuss in short about the socket programming in C. The basic consideration of socket programming is related to  networking.

Socket programming works on both TCP and UDP protocols. There are numerous applications like chat or FTP applications, which use socket programming for networking. Let us take an example and explore what socket programming is:

Consider an example of chat between you and your friend on Facebook:

1.      Facebook chat panel is considered as an “Endpoint” for communication.

2.      Both are having unique ID like your login “Address” and both are ready to listen any kind of chat in any form.

3.      Whenever you want to chat with your friend, you simply click on your friend’s icon in the list and start sending a message

          just like a “Caller”.

4.      After your message is sent, your friend will start receiving chat as a “Receiver”.

5.      As soon as this channel is established, you can start “Communicating” with your friend.

6.      Once you are finished with the conversation, you can “Close” the chat window anytime.

So in terms of Socket programming below analogies are used:

  •         Socket()                 :   Endpoint for communication
  •         Bind()                    :   Assign a unique ID.
  •         Listen()                 :   Wait for a chat.
  •         Connect()              :   Initialize chat.
  •         Accept()                 :   Accept chat from friend.
  •         Send(), Recv()      :   Start Chatting.
  •         Close()                   :   Hang up.

TCP connection process:

 

socket
The TCP 3-Way Handshaking Process in Socket Programming

 

Data Structure:

1.      Struct sockaddr       {
                                                    unsigned short sa_family;
                                                    char sa_data[14];
                                               }

2.      Struct sockaddr_in {
                                                  short sin_family;
                                                  unsigned short sin_port; // Port Number
                                                  struct in_addr sin_addr; // IP Address
                                                  char sin_zero[8];
                                              }

3.      Struct in_addr         {
                                                    unsigned long s_addr; // 4 bytes long
                                               }

As all of them are self explanatory, in most of the cases 1st type of struct is used and if any other type is used then it will be casted to type 1st.

Byte ordering:

2 type of byte ordering are used; Big Endian and Little Endian. All hosts uses Little Endian order, so before passing it to the network, bytes need to be converted into Little Endian.

Below functions are helpful to transform bytes:

  • Host Byte Order to Network Byte Order :   htons() , htonl()
  • Network Byte Order to Host Byte Order :   ntohs() , ntohl()

IP Address format: Before passing to the network; IP address should be converted into Network format (Binary Format).

  • ASCII dotted to Binary: inet_aton()
  • Binary to ASCII dotted: inet_ntoa()

 Functions used in C for socket programming:

1.      Socket Function : Endpoint

                          This function creates an endpoint for network connections.

                          Int Socket(int serverDomain, int typeOfConnection, int protocol)

                          serverDomain = PF_INET (IPv4 communication)

                          typeOfConnection = SOCK_STREAM (TCP) or SOCK_DGRAM (UDP)

                          protocol = 0 (For basic connection)

                          Return :  Descriptor on success and  -1 on an error.

2.      Bind Function : Bind IP and Port

                          Int Bind(int sockFuncDescriptor, struct sockaddr *server_addr, socklen_t *addressLength)

                          sockFuncDescriptor = socket descriptor returned by socket()

                          server_addr = pointer to a valid sockaddr_in structure cast as a sockaddr * pointer

                          addressLength= length of the sockaddr_in structure

3.      Listen Function : Wait for connection

                         Int Listen(int sock, int MaxConn)

                         sock = socket returned by socket()

                         MaxConn = Maximum length of the pending connections queue

4.      Accept Function :  Accept new connection from client.

                        Int Accept(int sock, (struct sockaddr *)&client, socklen_t *client_len)

                        sock = the socket in listen state

                        client =  A new client detail  when accept returns

                        client_len = pointer to size of the client structure

5.      Connect Function : Connect to client

                       Int Connect(int socker, (struct sockaddr *)&server_addr, socklen_t length)

                       socket : Return from socket()

                       server_addr : a sockaddr_in struct pointer filled with all the remote server details and  cast as a sockaddr struct pointer

                       length : size of the server_addr struct

6.      Send and Receive Function : As name depict

                            Int send(int socket, void *message, size_t length, int flag)

                            socket = A connected socket

                            message = Pointer to a message.

                            length = Size of the message buffer

                            flag = 0 (for now)

7.      Close Function:

                            Int close(int socket)
                            socket = The socket that need to be close.

Hello World C code for Socket:

#include<string.h>

#include<stdio.h>

#include<stdlib.h>

#include<sys/types.h>

#include<sys/socket.h>

#include<netinet/in.h>

#include<errno.h>

main()

{

            int sock, cli;

            struct sockaddr_in server, clientDetail;

            unsigned int len;

            char mesg[] = “Hello world with Socket programming!”;

            int sentconf;

             if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)

            {

                        perror(“There are some issue in creating socket : “);

                        exit(-1);

            }

             server.sin_family = AF_INET;

            server.sin_port = htons(10012);

            server.sin_addr.s_addr = INADDR_ANY;

            bzero(&server.sin_zero, 8);

             len = sizeof(struct sockaddr_in);

             if((bind(sock, (struct sockaddr *)&server, len)) == -1)

            {

                        perror(“Error in Binding”);

                        exit(-1);

            }

             if((listen(sock, 5)) == -1)

            {

                        perror(“Error in Listening”);

                        exit(-1);

            }

            while(1)

            {

                        if((cli = accept(sock, (struct sockaddr *)&clientDetail, &len)) ==-1)

                        {

                                    perror(“Error in Accepting”);

                                    exit(-1);

                        }

                         sentconf =  send(cli, mesg, strlen(mesg), 0);

                        printf(“Sending %d bytes to clientDetail : %c\n”, sentconf,                                                                 inet_ntoa(clientDetail.sin_addr));

                        close(cli);

            }

}

Hope you’ll find this useful. 🙂

Author : Amit Sharma

SHARE