Sockets

Today:

  • Background on TCP/UDP
  • Introduction to sockets
  • How to build a TCP client/server application
  • Some other functionality
  • Hands-on: an echo application
  • Going through homework
  • Background

    TCP: connection-oriented, makes sure data is delivered, sends packets again and again until everything is received, sends acknowledgments that data is received

    UDP: connectionless, does not guarantee delivery

    In the IP world:
    IP address is a 32-bit address that we usually write in 4 numbers separated by dots: 18.0.2.231

    Host name is a name that maps to an IP address that makes it easier to remember an address. Hostname web is the name of a web host in the mit.edu domain: web.mit.edu is the full name that maps to IP address: 18.69.0.38.

    To find this address, you can for example type at the athena prompt:

    athena% ping -s list.mit.edu 3 1

    (where 3 is the number of bytes sent, and 1 is the number of times this request is sent)

    PING list.mit.edu: 3 data bytes

    11 bytes from LIST.MIT.EDU (18.58.0.236): icmp_seq=0.
    ...

    Let us also define the concept of port. A port is an integer number that accompanies a networked application that lets it communicate independently of the other networked applications. For example, if you have a web server, it usually sits at port 80 for incoming requests. This server will not interfere with, say an FTP server on the same machine that is listening to port 21.

    Introduction to Sockets

    Basically, we need to send and receive data between two different hosts. The process of receiving and sending that data is Input/Output or I/O. The process of sending and receiving data over a network is called network I/O. Sockets constitute an interface to enable network I/O. File I/O based on the UNIX open-read-write-close is neither flexible nor complete enough to allow good network I/O

    Problems with that paradigm include:

    1. There is no ability to create server code that waits for connections passively or client code that forms connections actively
    2. By sending datagrams in a connectionless scheme, programs might want to specify a destination address along with each datagram, instead of binding destinations at the time when open() is called
    3. We also need to be able to specify the quality of a connection and the underlying protocol used (datagram, stream, etc.)

    No standard way devised for this I/O but a de facto interface: sockets.

    Sockets independent of network technology and therefore work with several network protocol families:

    TCP/IP (PF_INET),
    AppleTalk (PF_APPLETALK),
    Unix file system (PF_UNIX)

    They allow different types of data to be transmitted:

    SOCK_STREAM (e.g. Web access),
    SOCK_DGRAM (e.g. Real Audio and Real Video),
    SOCK_RAW (bit access)

    Can specify the protocol. For example, {PF_INET, SOCK_STREAM} defines TCP and {PF_INET, SOCK_DGRAM} defines UDP.

    Sockets are used in most networked applications.

     

    Steps in building a client-server architecture:

    Here we are discussing the client/server architecture using TCP.
    A server in a networked application is a program that sits on one host and listens passively for incoming traffic at a certain port.

    The web server sits web.mit.edu listens to port 80 or in other words (18.69.0.38:80).

    The client sits at the other end and is active. It send connection requests, writes data, receives data and closes the connection.

    When a server receives an incoming connect request, it answers by an accept, reads incoming data and writes outgoing data. It also closes the socket once the communication is finished.

     

    Client Side

    Server Side

    create: socket()

    create: socket()

     

    bind()

     

    listen()

    connect()

    accept()

    read()/write()

    read()/write()

    close()

    close()

      Note: all example code in provided in C, but you can also use any other language that provides a socket library.

    1. create one or more sockets on demand:
    2. int socket (int domain, int type, int protocol)

      e.g.

      client_socket = socket (PF_INET, SOCK_STREAM, 0);

      server_socket = socket (PF_INET, SOCK_STREAM, 0);

      client_socket and server_socket will be set to a negative number if no socket was created, positive or null otherwise

    3. for a client, connect to a (remote) server:
    4. int connect (int socket, struct sockaddr* destaddr, int addrlen)

      e.g.

      connect (client_socket, &server_address, sizeof (server_address));

      server_address is a structure that contains information about the server you are building, what port it listens to, what clients can connect to the server and what protocol is used:

      bzero(&server_address, sizeof(server_address)); // reset it

      server_address.sin_family = AF_INET; // internet protocol family

      server_address.sin_addr.s_addr = htonl(INADDR_ANY); // all addresses welcome

      server_address.sin_port = htons(PORT); // PORT is an integer e.g. 5501

       

      In the case of a server application, 3 steps:

      bind (socket, localaddr, addrlen)

      // establishes a local address for the socket

      listen (socket, backlog)

      // puts a socket in a passive mode, ready to accept a number (backlog) of connections at a time

      accept (socket, address, addrlen)

      // waits then accepts connection requests

      // address refers to the address of the client that has placed a request

    5. read() and write() function in pair: client can send
    6. int write (int socket, char* buffer, int length)

      e.g. write (server_socket, buffer, 1);

      in this case server should have:

      int read (int socket, char* buffer, int length)

      e.g. read (client_socket, buffer, 1);

      or vice versa

    7. close the socket

    close (socket)

    e.g.

    close (client_socket)

    Important and Helpful functionality

    How to look up a host by its name:

    gethostbyname(host)

    How to look up a host by its address:

    gethostbyaddr(address, length, type)

    where length = sizeof(address) and type = AF_INET 


    In order to use connectionless service, such as UDP, one can use recvfrom() and sendto() instead of read() and write().
    recvfrom() and writeto() are usually associated with connectionless traffic though because both source address is always sent with the data.

    recvfrom(socket, buffer, length, flags, address, &addrlen);

    where you will use flags as 0 and address of the sending host sendto(socket, buffer, length, flags, address, addrlen);
    where you will use flags as 0 and address of the sending host

    To find about the functionality of a certain command (function), type at the athena prompt, the man command followed by the function name:

    athena% man gethostbyname
    will give help information on gethostbyname()

    Client and Server files

    tcpechoclient.c
    tcpechoserver.c

    To compile on athena, save the files locally. Afterwards, execute from the athena prompt:

    athena% gcc tcpechoclient.c -lsocket -o tcpechoclient
    athena% gcc tcpechoserver.c -lsocket -o tcpechoserver

    To run on athena, open a new xterm by typing:

    athena% xterm &

    In one of the xterms, you can run the server by typing:

    athena% tcpechoserver

    In the other xterm, run the client:

    athena% tcpechoclient (server IP address)
    where server IP address can be found by executing ping as mentioned earlier

    Homework available at this link: homework.txt