TCP Sockets

Socket Address Structure

 

UtilityFunctions:

Byte Order

Byte Manipulation

Conversion Functions

Read/Write

 

Socket Functions:

Connect

Bind

Listen

Accept

Close

 

 

 


Ø   Socket Address Structures:

 

 

struct  in_addr   {
     in_addr_t     s_addr ;   // 32-bit, IPv4 net byte order
}

struct   sockaddr_in {
                              sin_len
                              sin_family
                              sin_ port
struct   in_addr   sin_addr
                              sin _zero[8]
}

Example:

In  TCP daytime Server:
 

struct  sockaddr_in   servaddr;

….
servaddr.
sin_addr.s_addr = htonl (INADDR_ANY);

 

If you like to find the value of any constant (e.g., INADDR_ANY) compile the program as:

 

%  gcc –E prog.c > t

 

and look at t.

 

 

Generic socket address structure


Used for args to socket functions.
(These functions developed for many protocols, IPv4, IPv6, UNIX, etc..) 

        struct sockaddr {

                     sa_len
                     sa_family
      char       sa_data [14]
}

 

Example:

 

Struct   sockaddr_in      Serv;  // IPv4
Struct   sockaddr_in6    Serv;  // IPv6

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

OR  
       
#define  SA      struct  sockaddr

bind (sockdf,    (SA *) &Serv,   sizeof(Serv))

 

 


Ø    Utility Functions

ü Byte Order Functions   

 

little-endian  &  big-endian
 

htons    host to network  short
htonl            ...                  long
ntohs
ntohl

See example: ~/stevens2nd.book/unpv12e/intro/byteorder.c

 

ü Byte Manipulation Functions   

 

bzero        memset
bcopy       memcpy
bcmp        memcmp

 

% man -s 3c   bstring

% man -s 3c   memory

 

 

ü Conversion Functions
 

Convert from dotted-decimal (e.g., 128.82.4.7) to   32-bit network byte order binary value.

inet_pton   presentation   to    numeric
inet_ntop   numeric         to    presentation

 

For details see:

 

% man   inet

 

 

 

ü Read/Write Utility Functions
 

lib/readn.c :   Read "n" bytes from a descriptor.
lib/writen.c : Write "n" bytes to a descriptor.
lib/readline.c: Read line from a descriptor.

lib/isfdtype.c: test type of a descriptor

 

            (e.g.,  if ( isfdtype (fd, S_IFSOCK)  = = 1) it is socket). 

 

 See example: ~/stevens2nd.book/unpv12e/intro/fdtypetest.c

 

               % fdtypetest

               % telnet localhost 10313

 

 


Ø    Socket Functions

 

 

  

Description: fig4_1 

 

Figure: Socket Functions for elementary TCP client-server

ü  Connect:

    Send SYN....&

       after 6 seconds..&

                after 24 seconds


     if  after 75 seconds no SYN,ACK received
          ETIMEOUT is returned.

     if  server responds with RST (no process waiting at port)
          ECONNREFUSED is  returned.

     if  a router returns ICMP destination unreachable
          send after 6 and 24 seconds and if no connection after 75 seconds
         EHOSTUNREACHE is returned.

NOTE: This is implementation-dependent.

         You may use tcpdump to check your particular implementation.

 

        (e.g., use tcpServer0 & tcpClient0 with tcpdump):

 

somethingelse % tcpServer0 1233

something % tcpClient0  somethingelse 1233

 

«  You can't reconnect the socket to another address

unless  you close and call socket again.

 

 


ü  Bind:          

Server: Normally bind to a well know port & INADDR_ANY.

§  Using port# 0: kernel chooses a free port and  we use getsockname to find the selected port.

§  When a connection is accepted, the IP address of the connection is  fixed and  we use getsockname to find the interface IP address.

§  You can bind to specific IP address X instead of INADDR_ANY, only connection to this address X is accepted.

Client:  Normally clients do not bind to any specific port or address.

§  As part of connect bind is implicitly called.

§  Any ephemeral port and interface IP address is filled based on the routing table.

§  Use getsockname to find out the port and address.

 

 

 


ü  Listen:
 

Description: fig4_6_7

 Figure: Listen Backlog Queues

 

 

Description: fig4_9 

 

Figure: Queues Statistics

 

 


Statistics:

The above is the observations of the queue lengths for an HTTP server with backlog value of 64

        Example: 

        Out of   90,924  times tested the values of the queues:

ü 90,358  times we found the completed queue is empty  (i.e., 99.4% of time it is empty).

ü 3,033  times we found the  incomplete queue empty (i.e,   3.4% of time it is empty).

 

If for any reason the queue is full, simply do nothing and the client tries 3 times and then give up.

 

 


ü  Accept:

 

S2 = accept (S1, ....)


S1 is the listining socket
S2 is the connected socket.

 

getsockname return the same port number for S1 and S2 and both are equal.

Note that demultiplexing is done based on the  source address and port  of the client since the connection is identified by 4 topples: <localIP, localPort, foreignIP, foreignPort>

 

Concurrent Server:

Figure: Exec functions

Figure: Concurrent Server Outline

Figure: Accept 

Figure: Fork

 

 


ü     Close

 

TCP will send queued data and then send FIN segment.

(unless SO_LINGER option is used to discard unsent data)

 

 

               ling.l_onoff = 1;              /* cause RST to be sent on close() */

          ling.l_linger = 0;

          setsockopt ( sockfd, SOL_SOCKET,  SO_LINGER, &ling,  sizeof(ling) );

          close (sockfd);