Sockets Programming

Network Application Programming Interface (API)

Network API

Generic Programming Interface

TCP/IP

Functions needed:

  • Specify local and remote communication endpoints
  • Initiate a connection
  • Wait for incoming connection
  • Send and receive data
  • Terminate a connection gracefully
  • Error handling

    Berkeley Sockets

    Socket

    Unix Descriptor Table

    Socket Descriptor Data Structure

    Creating a Socket

    int socket(int family,int type,int proto);

    socket()

    Specifying an Endpoint Address

    Generic socket addresses

    	struct sockaddr {
    		u_short	   sa_family; 
    		char	   sa_data[14];
    	};
    

    sockaddr

    AF_DAVESKIDS

    AF_INET

    struct sockaddr_in

    struct sockaddr_in {
    
    		u_short	       sin_family;
    
    		u_short	   	   sin_port;
    
     		struct in_addr  sin_addr; 
    
    		char	            sin_zero[8];
    
    	};
    

    struct in_addr

    struct in_addr {
    
    	 u_long s_addr;	 /* IP ADDRESS */
    
    };
    
    
    
    in_addr just provides a name for the 'C' type associated with IP addresses.
    
    

    Network Byte Order

    • All values stored in a sockaddr_in must be in network byte order.
      • sin_port a TCP/IP port number.
      • sin_addr an IP address.

    TCP/IP Addresses

    • We don't need to deal with sockaddr structures since we will only deal with one protocol family.
    • We can always use sockaddr_in structures.
    • The C functions that make up the sockets API expect structures of type sockaddr.

    Assigning an address to a socket

    • The bind() system call is used to assign an address to an existing socket.
      int bind( int sockfd, struct sockaddr *myaddr, int addrlen);
      
    • bind returns 0 if successfull or -1 on error.

    bind()

    • calling bind() assigns the address specified by the sockaddr structure to the socket descriptor.
    • You can give bind() a sockaddr_in structure:
         bind( mysock, (struct sockaddr*) &myaddr, sizeof(myaddr) );
      

    bind() Example

    int mysock;
    
    struct sockaddr_in myaddr;
    
      mysock = socket(PF_INET,SOCK_STREAM,0);
    
      myaddr.sin_family = AF_INET;
    
      myaddr.sin_port = htons( portnum );
    
      myaddr.sin_addr = htonl( ipaddress);
    
      bind(mysock, &myaddr, sizeof(myaddr));
    
    

    Uses for bind()

    • There are 3 uses for bind():
      • Server would like to bind to a well known address (port number).
      • Client can bind to a specific port.
      • Client can ask the O.S. to assign any available port number.

    Port schmort - who cares ?

    • Clients typically don't care what port they are assigned.
    • When you call bind you can tell it to assign you any available port:
      	myaddr.port = htons(0);
      

    What is my IP address ?

    • How can you find out what your IP address is so you can tell bind() ?
    • There is no realistic way for you to know the right IP address to give bind() - what if the computer has multiple network interfaces?
    • specify the IP address as: INADDR_ANY, this tells the OS to take care of things.

    Other socket system calls

    • General Use
      • read()
      • write()
      • close()
    • Connection-oriented (TCP)
      • connect()
      • listen()
      • accept()
    • Connectionless (UDP)
      • send()
      • recv()