Linux Socket Programming


Server Programming


To accept connections, the following steps are performed:
  1. A socket is created with socket().
  2. 
    #define SERVER_ADDR "127.0.0.1"
    #define SERVER_PORT 6666 
    
     if ( (sock_fd=socket(AF_INET, SOCK_STREAM,0)) < 0 ){
      exit(1);
      }
    
     if ( setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &rc, sizeof(rc)) == -1 )
     {
     exit(1);
     }
    
  3. The socket is bound to a local address using bind(), so that other sockets may be connect()ed to it.
  4. 
     bzero((char *) &serv_addr, sizeof(serv_addr));
     serv_addr.sin_family = AF_INET;
     inet_aton(SERVER_ADDR,&(serv_addr.sin_addr.s_addr));
     serv_addr.sin_port = htons(SERVER_PORT);
     while ( bind(sock_fd, (struct socaddr *) &serv_addr, sizeof(serv_addr)) < 0 ){
      sleep(1);
      }
    
  5. A willingness to accept incoming connections and a queue limit for incoming connections are specified with listen().
  6. 
     listen(sock_fd, 5);
    
    listen() marks the socket referred to by sock_fd as a passive socket, that is, as a socket that will be used to accept incoming connection requests using accept(). The 2nd argument defines the maximum length to which the queue of pending connections for sock_fd may grow.
  7. Connections are accepted with accept().
  8. 
     // the select can detect the TCP connection event then call accept without doubt */
     FD_ZERO(&allset);
     FD_SET(sock_fd, &allset);
     FD_SET(app_fd, &allset);
     while (1) {
            rset = allset;
            timeout_ptr = NULL; 
            nready = select(maxfd+3+maxi, &rset, 0,0, timeout_ptr);
            // check sockets 
            if ( nready > 0 ){
                if ( FD_ISSET(sock_fd, &rset) ){ // used for accept a new connection
                    cli_len = sizeof(cli_control_addr);
                    if ( (app_fd = accept(sock_fd,  (struct sockaddr *)&cli_control_addr, &cli_len)) < 0 )
                        perror("masa: app_fd accept()");
    
                    FD_SET(app_fd, &allset); // add new descriptor to the set
    
                    /* messages can be communicated via the new app_fd now */
                    .....
                }
    
               if ( FD_ISSET(app_fd, &rset) ) { // a message arrived
    
               }
    
           }
    }// while
    
    The accept() system call:
    • extracts the first connection request on the queue of pending connections for the listening socket, sock_fd
    • creates a new connected socket, and returns a new file descriptor referring to that socket
    The newly created socket is not in the listening state. The original socket sockfd is unaffected by this call.

Client Programming



 int                  sockfd,i=1;
 struct sockaddr_in   serv_addr;
  
 /* open a TCP socket */
 if ( (sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
    {
     perror("api_connect:  can't open stream socket\n");
     return -1;
    }
 if ( setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *) &i, sizeof(i)) == -1 )
 {
 perror("api_connect: SO_REUSEADD");
 return -1;
 }   
 /* Fill the server's address */
 bzero( (char *) &serv_addr,sizeof(serv_addr) );
 serv_addr.sin_family =  AF_INET;
 inet_aton(SERVER_ADDR,&(serv_addr.sin_addr.s_addr));
 serv_addr.sin_port = htons(SERVER_PORT);
 if ( connect(sockfd, (struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0 )
    {
     perror("api_connect: can't bind local address\n");
     close(sockfd);
     return -1;
    }
The connect() system call connects the socket referred to by the file descriptor sockfd to the address specified by serv_addr.

留言

熱門文章