为什么我的服务器不能正确地同时执行 运行?

Why won't my server implementation run concurrently properly?

我正在尝试创建一个 client/server 系统,它可以使用 unix 系统调用 fork 处理多个并发连接。

客户端输入电影名称,服务器会检查电影是否存在。如果有的话,会告诉客户端排名,名字,箱子记录。

查看我的分叉实现,客户端要求用户输入,但程序只是简单地通过它。

输出示例:

connection made with client 127.0.0.1
PID IS 27270


 --> all messages read - connection being closed
CLIENT: Please input an string: PID IS 0

在这一行,CLIENT: Please input an string: PID IS 0,用户本应输入一个字符串,但程序只是扫视了一下。如何让程序接收来自客户端的字符串?

服务器代码:

int main()
{
   int                sock, clientsock, mlen, addrsize, msgct, chc, chct, pid;
   struct sockaddr_in addr; //ipv4 address
   char                ch, buf[80];

   /*
    * Create a socket.
    */

   sock = socket(AF_INET, SOCK_STREAM,0); //create socket (AF_NET shows its ipv4 internet connection, SOCK_STREAM shows its a tcp)
   if (sock == -1)
   {   
      perror("opening socket");
      exit(-1);
   }

   //Bind socket to local address
   /*
    * Bind a name to the socket.  Since the server will bind with
    * any client, the machine address is zero or INADDR_ANY.  The port
    * has to be the same as the client uses.
    */

   addr.sin_family = AF_INET;
   addr.sin_port = htons (32351); //port number for local address
   addr.sin_addr.s_addr = htonl (INADDR_ANY); //ip address (you can also hard code it) 

   if (bind(sock, (struct sockaddr *) &addr, //binding, first parameter : is the socket you created, &addr is the 
      sizeof (struct sockaddr_in)) == -1) //error checking
   {  
      perror ("on bind");
      exit (-1);
   } //(at this moment we have binded socket)

   /*
    * Make the socket available for potential clients.
    */

   //if there is connection or not?
   if (listen(sock,1) == -1)  
   {  
      perror("on listen");
      exit(-1);
   }


   //-------Text File Implementation-----------
   FILE *fp;
   char data[5][200];

   char rank[5][2];
   char name[5][255];  
   char value[5][100];

   /* opening file for reading */
   fp = fopen("movie.txt", "r");
   if(fp == NULL) {
      perror("Error opening file");
      return(-1);
   }

   fgets (data[0], 200, fp);
   int i = 1;

   while(fgets (data[i], 200, fp)!=NULL)
   {
      /* writing content to stdout */
      sscanf(data[i],"%s %[^$] %s",rank[i],name[i],value[i]);
      puts(data[i]);
      i+=1;
   }

   //CODE DOES NOT IMPLEMENT AFTER THIS WHILE LOOP

   //close the file 
   fclose(fp);

   addrsize = sizeof(struct sockaddr_in);

   //THIS WHILE LOOP IS NOT BEING IMPLEMENTED...

   while(1)
   {
      clientsock = accept(sock, (struct sockaddr *) &addr, &addrsize);
      if (clientsock == -1)//error checking
      {  
         perror("on accept");
         exit(-1);
      }
      printf("connection made with client ");

      printf ("%s\n", inet_ntoa (addr.sin_addr)); //also print client address

      /* Create child process */
      pid = fork();
      if (pid < 0)
      {
         perror("ERROR on fork");
         exit(1);
      }

      if (pid == 0)
      {
         /* This is the client process */
         close(sock);

         bool exist = false;

         mlen = recv (clientsock, buf, 80, 0);
         if (mlen < 0)
         {
            perror("ERROR reading from socket");
            exit(1);
         }

         int lenS;
         int which;
         for(int i = 1; i<5; i++)
         {
            printf("%s\n\n", name[i]);

            char *pch = strstr(name[i],buf);

            if(pch != NULL)
            {
                which = i;
                exist = true;
                puts("GOOD");


            }
            else
            {
               puts("bad");
            }
         }

         if(exist)
         {

            //SEND TO CLIENT FROM HERE!
            printf("%s\n", rank[which]);
            printf("%s\n", name[which]);
            printf("%s\n", value[which]);

            lenS = strlen(name[which]);
            send (clientsock, name[which], lenS+1, 0);
         }
         else
         {
            //SEND TO CLIENT FROM HERE!!!!
            printf("NOT HERE ");
            send (clientsock, "NOT HERE", 9, 0);
         }

         printf("Here is the message: %s\n",buf);

         exit(0);
      }
      else
      {
         close(clientsock);
         printf(" --> all messages read - connection being closed\n");
      }
   }
}

客户代码:

int main()
{
   int                sock, addrsize;
   struct sockaddr_in addr;
   unsigned int       in_address;
   char buf[80];
   int mlen;

   /* 
    * Open a socket for Internet stream services.
    */

   sock = socket(AF_INET, SOCK_STREAM,0); //creating a socket to connect to server, AF_INET : ipv4 internet connection, SOCK_STREAM tcp
   if (sock == -1)
   {   perror("opening socket");
       exit(-1);
   }

   addr.sin_family = AF_INET; 
   addr.sin_port = htons (32351); //port number has to be the same as the one from server
   in_address = 127 << 24 | 0 << 16 | 0 << 8 | 1; //ip address, local host, since we are running client and server on the same computer, it needs to have the same ip address
   addr.sin_addr.s_addr = htonl (in_address);

   if (connect (sock, (struct sockaddr *) &addr,  //binding
       sizeof (struct sockaddr_in)) == -1)
   {   
      perror("on connect");
      exit(-1);
   } 

   char word[100];
   int len;

   printf("CLIENT: Please input an string: ");
   scanf("%s", word);

   //printf("You entered: %s\n", word);
   len = strlen(word);

   send (sock, word, len+1, 0);

   mlen = recv (sock, buf, 80, 0);
   printf ("%s\n\n\n\n\n\n\n", buf);

   /* 
    * Do a shutdown to gracefully terminate by saying - "no more data"
    * and then close the socket -- the shutdown is optional in a one way
    * communication that is going to terminate, but a good habit to get
    * into. 
    */

   if (shutdown(sock, 1) == -1)
   {  
      perror("on shutdown");
      exit(-1);
   }
   printf ("Client is done\n");
   close(sock);
}

您运行将客户端和服务器程序安装在同一台机器上,具有相同的控制终端。服务器主进程、它的客户端服务子进程和独立的客户端进程因此都可以写入该终端。它们 运行 独立且同时进行,因此它们的输出可以混合在一起。

提示后发出 PID IS 0 消息的事实并不表示客户端程序已跳过接受输入,事实上,我不明白它是怎么做到的。提示和PID消​​息来自不同的进程。

从不同的(虚拟)终端启动服务器进程和客户端进程会让事情变得更清楚,这样它们的输出就不会混合。