Skip to content
Snippets Groups Projects
Select Git revision
  • a37ad63654237a3c34115a8fe63f2f4796a6be74
  • master default protected
2 results

README.md

Blame
  • mysever.c 4.67 KiB
    
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #include <netinet/in.h>
    #include <ctype.h>
    #include <arpa/inet.h>
    
    #include <fcntl.h>
    #include <netdb.h>
    
    #include <string.h>
    #include <strings.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <unistd.h>
    #define MAXFD 2
    
    int main(int argc, char ** argv)
    {
        int sockfd, newsockfd, portno; // clilen;
        char buffer[256];
        struct sockaddr_in serv_addr, cli_addr;
        socklen_t clilen;
        int n;
        char * c;//
    
        if (argc < 3)
        {
            fprintf(stderr, "usage: %s ip port\n", argv[0]);
            return 0;
        }
    
        /* Create TCP socket */
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0)
        {
            perror("ERROR opening socket");
            exit(EXIT_FAILURE);
        }
    
        // reuse the socket if possible
        int const reuse = 1;
        if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int)) < 0)
        {
            perror("setsockopt");
            exit(EXIT_FAILURE);
        }
    
        portno = atoi(argv[2]);
    
        /* Create address we're going to listen on (given port number)
         - converted to network byte order & any IP address for this machine */
        bzero((char *)&serv_addr, sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_addr.s_addr = INADDR_ANY;//differ
        serv_addr.sin_port = htons(portno); // store in machine-neutral format
    
        /* Bind address to the socket */
        if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
        {
            perror("ERROR on binding");
            exit(EXIT_FAILURE);
        }
    
        /* Listen on socket - means we're ready to accept connections -
         incoming connection requests will be queued */
        listen(sockfd, 5);
    
        clilen = sizeof(cli_addr);
    
        /* Accept a connection - block until a connection is ready to
         be accepted. Get back a new file descriptor to communicate on. */
        /*newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
        if (newsockfd < 0)
        {
            perror("ERROR on accept");
            exit(EXIT_FAILURE);
        }*/
    
        // initialise an active file descriptors set
        fd_set masterfds;
        FD_ZERO(&masterfds);
        FD_SET(sockfd, &masterfds);
        // record the maximum socket number
        int maxfd = sockfd;
    
        while (1)
        {
          // monitor file descriptors
          fd_set readfds = masterfds;
          if (select(FD_SETSIZE, &readfds, NULL, NULL, NULL) < 0)
          {
              perror("select");
              exit(EXIT_FAILURE);
          }
    
          // loop all possible descriptor
          for (int i = 0; i <= maxfd; ++i)
              // determine if the current file descriptor is active
              if (FD_ISSET(i, &readfds))
              {
                  // create new socket if there is new incoming connection request
                  if (i == sockfd)
                  {
                      int newsockfd = accept(sockfd, (struct sockaddr *)&cliaddr, &clilen);
                      if (newsockfd < 0)
                          perror("accept");
                      else
                      {
                          // add the socket to the set
                          FD_SET(newsockfd, &masterfds);
                          // update the maximum tracker
                          if (newsockfd > maxfd)
                              maxfd = newsockfd;
                          // print out the IP and the socket number
                          /*char ip[INET_ADDRSTRLEN];
                          printf(
                              "new connection from %s on socket %d\n",
                              // convert to human readable string
                              inet_ntop(cliaddr.sin_family, &cliaddr.sin_addr, ip, INET_ADDRSTRLEN),
                              newsockfd
                          );*/
                      }
                  }
                  // a message is sent from the client
                  else
                  {   /* Read characters from the connection, then process */
                      char buff[256];
                      int n = read(i, buff, 256);
                      if (n <= 0)
                      {
                          if (n < 0)
                              perror("read");
                          else
                              printf("socket %d close the connection\n", i);
                          close(i);
                          FD_CLR(i, &masterfds);
                      }
                      // write back to the client
                      else if (write(i, buff, n) < 0)
                      {
                          perror("write");
                          close(i);
                          FD_CLR(i, &masterfds);
                      }
                  }
              }
    
    
    
            if (!strncmp(buffer, "GOODBYE-CLOSE-TCP", 17))
                break;
    
            /*c = buffer;
            while (*c)
            {
                *c = toupper(*c);
                ++c;
            }*/
    
    
    
        /* close socket */
        //close(sockfd);
    
        return 0;
    }