2014-11-05 106 views
0

如何鏈接這些客戶端和服務器程序在同一臺機器上我使用Linux env通過USB做我需要打開兩個窗口的終端?其次我所提供的端口號自己其給錯誤「ADRESS已在使用」我怎樣才能避免這種錯誤,我怎麼能編譯它們同一臺機器上我的主機名是「Ubuntu的」步驟請你告訴鏈接服務器和客戶端

   /* 
      ** server.c -- a stream socket server demo 
      */ 

      #include <stdio.h> 
      #include <stdlib.h> 
      #include <unistd.h> 
      #include <errno.h> 
      #include <string.h> 
      #include <sys/types.h> 
      #include <sys/socket.h> 
      #include <netinet/in.h> 
      #include <netdb.h> 
      #include <arpa/inet.h> 
      #include <sys/wait.h> 
      #include <signal.h> 

      #define PORT "3490"  // the port users will be connecting to 

      #define BACKLOG 10 // how many pending connections queue will hold 

      void sigchld_handler(int s) 
      { 
       while(waitpid(-1, NULL, WNOHANG) > 0); 
      } 

      // get sockaddr, IPv4 or IPv6: 

      void *get_in_addr(struct sockaddr *sa) 
      { 
       if (sa->sa_family == AF_INET) 
       { 
        return &(((struct sockaddr_in*)sa)->sin_addr); 
       } 

        return &(((struct sockaddr_in6*)sa)->sin6_addr); 
      } 

      int main(void) 
      { 
       int sockfd, new_fd;      // listen on sock_fd, new connection on new_fd 
       struct addrinfo hints, *servinfo, *p; 
       struct sockaddr_storage their_addr;  // connector's address information 
       socklen_t sin_size; 
       struct sigaction sa; 
       int yes=1; 
       char s[INET6_ADDRSTRLEN]; 
       int rv; 

       memset(&hints, 0, sizeof hints); 
       hints.ai_family = AF_UNSPEC; 
       hints.ai_socktype = SOCK_STREAM; 
       hints.ai_flags = AI_PASSIVE;    // use my IP 

       if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) 
       { 
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); 
        return 1; 
       } 

       // loop through all the results and bind to the first we can 

       for(p = servinfo; p != NULL; p = p->ai_next) 
       { 
        if ((sockfd = socket(p->ai_family, p->ai_socktype,p->ai_protocol)) == -1) 
        { 
         perror("server: socket"); 
         continue; 
        } 

        if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes,sizeof(int)) == -1) 
        { 
         perror("setsockopt"); 
         exit(1); 
        } 

        if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) 
        { 
         close(sockfd); 
         perror("server: bind"); 
         continue; 
        } 

        break; 
       } 

       if (p == NULL) 
       { 
        fprintf(stderr, "server: failed to bind\n"); 
        return 2; 
       } 

       freeaddrinfo(servinfo); // all done with this structure 

       if (listen(sockfd, BACKLOG) == -1) { 
        perror("listen"); 
        exit(1); 
       } 

       sa.sa_handler = sigchld_handler; // reap all dead processes 
       sigemptyset(&sa.sa_mask); 
       sa.sa_flags = SA_RESTART; 
       if (sigaction(SIGCHLD, &sa, NULL) == -1) { 
        perror("sigaction"); 
        exit(1); 
       } 

       printf("server: waiting for connections...\n"); 

       while(1) 
        { 
         // main accept() loop 

         sin_size = sizeof their_addr; 
         new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size); 
         if (new_fd == -1) 
         { 
         perror("accept"); 
         continue; 
         } 

         inet_ntop(their_addr.ss_family,get_in_addr((struct sockaddr *)&their_addr),s, sizeof s); 
         printf("server: got connection from %s\n", s); 

         if (!fork()) 
         { 
         // this is the child process 

         close(sockfd); // child doesn't need the listener 
         if (send(new_fd, "Hello, world!", 13, 0) == -1) 
         perror("send"); 
         close(new_fd); 
         exit(0); 
         } 
          close(new_fd); // parent doesn't need this 
       } 

       return 0; 
      } 

回答

0

打開兩個終端。在一次運行服務器進程。而在另一個運行您的客戶端使用您的本地主機(大多數是127.0.0.1),並提供相同的端口號。如果在終端中已經運行了服務器程序,然後又想在同一個終端中再次運行相同的服務器程序,那麼它將使用已經使用的端口地址。只需關閉終端並打開一個新的終端。