gtpc1m3eTransmission Control Protocol/Internet Protocol

Main Socket Function Calls

Following are examples of code segments showing the main socket function calls and the input and output for the calls.

  1. Allocate a socket descriptor:
    socket function call

    int socket(int domain, int type, int protocol);
    
    ·
    ·
    ·
    int server_sock;
    ·
    ·
    ·
    server_sock = socket(AF_INET, SOCK_STREAM, 0);

    The previous example allocates socket descriptor server_sock in the internet addressing family, AF_INET, using a socket stream type and the default protocol TCP indicated by 0.

  2. You can bind an address to a socket in two ways:
    1. Explicitly bind a unique address to the socket:
      bind function call

      int bind(int s, struct sockaddr *name, int namelen);
      
      ·
      ·
      ·
      int rc; int server_sock; struct sockaddr_in myname;
      ·
      ·
      ·
      memset(&myname, 0, sizeof(myname)); myname.sin_family = AF_INET; myname.sin_port = 5001; myname.sin_addr.s_addr = inet_addr("129.5.24.1");
      ·
      ·
      ·
      rc = bind(server_sock, (struct sockaddr *) &myname, sizeof(myname));

      The previous example binds socket server_sock to internet address 129.5.24.1 and port 5001.

      In this example, the network address and the port address were in the network byte order:

      inet_addr was used to convert a character internet address to network byte order.

      See each of these functions in the alphabetic reference section of Socket Application Programming Interface Functions Reference.

    2. Bind an address to the socket using a wild card:
      bind function call

      int bind(int s, struct * *name, int namelen);
      
      ·
      ·
      ·
      int rc; int server_sock; struct *_in myname;
      ·
      ·
      ·
      memset(&myname, 0, sizeof(myname)); myname.sin_family = AF_INET; myname.sin_port = 5001; myname.sin_addr.s_addr = INADDR_ANY; /* all interfaces */ rc = bind(s, (struct sockaddr *) &myname, sizeof(myname));

    Note:
    If a socket application with the wildcard option issues a bind to an offload device in a multiple offload device configuration, and the offload device is deactivated, the socket application remains active if there is another active offload device in the configuration.
  3. The server indicates its readiness to accept connections from clients:
    listen function call

    int listen(int s, int backlog);
    
    ·
    ·
    ·
    int rc; int server_sock;
    ·
    ·
    ·
    rc = listen(server_sock, 5);

    This example indicates that the server is ready to accept calls, and that a maximum of 5 connect requests can be queued for the server. Additional requests are ignored.

    Note:
    If the backlog is less than 0, it is set to 0. The backlog value is set in SOMAXCONN.
  4. The client starts a connection request:
    connect function call

    int connect(int s, struct sockaddr *name, int namelen);
    
    ·
    ·
    ·
    int rc; int client_sock; struct sockaddr_in servername;
    ·
    ·
    ·
    memset(&servername, 0, sizeof(servername)); servername.sin_family = AF_INET; servername.sin_port = 5001; servername.sin_addr.s_addr = inet_addr("129.5.24.1");
    ·
    ·
    ·
    rc = connect(server_sock, (struct socaddr *) &servername, sizeof(servername));

    This example connects socket client_sock to the server with an address servername. This is the same server that was shown in the previous bind. The client could optionally be blocked until the connection is accepted by the server. On a successful return, socket server_sock is associated with the connection to the server.

  5. The server accepts the client's connection request:
    accept function call

    int accept(int s, struct sockaddr *addr, int *addrlen);
    
    ·
    ·
    ·
    int addrlen; int newclient_sock; int server_sock; struct sockaddr client_addr;
    ·
    ·
    ·
    addrlen = sizeof(client_addr); newclient_sock = accept(server_sock, &client_addr, &addrlen);

    When the server accepts a connection request on socket server_sock, the name of the client and the length of the client name are returned, along with a new socket descriptor. The new socket descriptor is associated with the client that began the connection, and server_sock is available to accept new connections.

  6. The client and server transmit data in the connected state:
    send and recv function calls

    int send(int s, char *msg, int len  int flags);
    int recv(int s, char *msg, int len, int flags);
    
    ·
    ·
    ·
    int client_sock; int bytes_sent; int bytes_recv; char data_sent[256]; char data_recv[256];
    ·
    ·
    ·
    bytes_sent = send(client_sock, data_sent, sizeof(data_sent), 0);
    ·
    ·
    ·
    bytes_recv = recv(client_sock, data_recv, sizeof(data_recv), 0);

    The previous example shows an application sending data on a connected socket and receiving data in response. The flag fields can be used to specify additional options for send or recv.

    Clients and servers can use many function calls to transfer data, such as:

  7. The client and server transmit data when they are in the connectionless state:
    sendto and recvfrom function calls

    int sendto(int socket, char *buf, int buflen, int flags;
               struct sockaddr *addr, int addrlen);
    int recvfrom(int socket, char *buf, int buflen, int flags;
               struct sockaddr *addr, int addrlen);
    
    ·
    ·
    ·
    int addrlen; int client_sock; int bytes_sent; int bytes_recv; char data_send[256]; char data_recv[256]; struct sockaddr_in from_addr; struct sockaddr_in to_addr;
    ·
    ·
    ·
    addrlen = sizeof(struct sockaddr_in); memset(&to_addr, 0, addrlen); to_addr.sin_family = AF_INET; to_addr.sin_port = 5001; to_addr.sin_addr.s_addr = inet_addr("129.5.24.1");
    ·
    ·
    ·
    bytes_sent = sendto(client_sock, data_sent, sizeof(data_sent), 0, (struct sockaddr *)&to_addr, addrlen);
    ·
    ·
    ·
    bytes_recv = recvfrom(client_sock, data_recv, sizeof(data_recv), 0,(struct sockaddr *)&from_addr, &addrlen);

    If the socket is not connected, additional socket address information must be passed to sendto and can be optionally returned from recvfrom. The caller must specify the recipient of the data or to be notified of the sender of the data.

    Usually, sendto and recvfrom are used for datagram sockets; read, send, and recv are used for stream sockets.

  8. Client and server can receive data using a special TPF function call called activate_on_receipt:
    activate_on_receipt function call issued from ECB 1

    int accept(int s, struct sockaddr *addr, int *addrlen);
    int activate_on_receipt(unsigned int s,
                            unsigned char *parm,
                            unsigned char *pgm);
    
    ·
    ·
    ·
    int addrlen; int newclient_sock; int server_sock; char aorparm[8]; char aorpgm[4] = "abcd";
    ·
    ·
    ·
    newclient = accept(server_sock, (struct sockaddr *)0, (int *)0);
    ·
    ·
    ·
    /* No parameters will be passed to the new ECB */ memset(aorparm,0,sizeof(aorparm)); rc = activate_on_receipt(newclient, aorparm, aorpgm);

    The activate_on_receipt function call allows the issuing ECB to exit and activates a different ECB at program abcd. After the information has been received, the activated program, called the child server program, must issue a read, recv, or recvfrom function call to receive the information. See activate_on_receipt -- Activate a Program after Data Received for more information.

    read function call issued from ECB 2

    :
    abcd()
    {
      
    ·
    ·
    ·
    int bytes_recv; int newclient_sock; int msg_length; char *read_addr;
    ·
    ·
    ·
    /* socket descriptor, buffer address, and message */ /* length are returned in ECB */ newclient_sock = (int)ecbptr()->ebrout; memcpy(&read_addr,&(ecbptr()->ebw012),sizeof(read_addr)); memcpy(&msg_length,&(ecbptr()->ebw016),sizeof(msg_length)); bytes_recv = read(newclient_sock,read_addr,msg_length);
    ·
    ·
    ·
    }
  9. Deallocate the socket descriptor:
    close function call

    int close(int s);
    
    ·
    ·
    ·
    int rc; int server_sock;
    ·
    ·
    ·
    rc = close(server_sock);

    In the previous example socket server_sock is closed. The close call shuts down the socket descriptor server_sock and frees up its resources.