0

私は特定のクライアントに接続しており、通信しています。別のクライアントが私のサーバーに接続し、新しい接続があることを即座に出力します..eg、他のクライアントをリッスンしながら受け入れますか?..どうすればできますか?..

私はすでに機能しているものを持っていますが、一度に1つのことしかできません。既にクライアントと通信している場合、他のクライアントへの着信接続またはデータを受け入れることができません。通信しているクライアントが切断されている場合にのみ、他のクライアントからの新しい接続またはデータを受け入れることができます。クライアントの受け入れとリッスンの両方を同時に処理できるようにするにはどうすればよいですか。スレッドを使用したくありません。

これが私のコードの一部です。

do
{
   fduse = fdin;
   printf("Waiting for Connection\n");
   err = select(sMax + 1, &fduse, NULL, NULL, NULL);
   if (err < 0)
   {
      perror("  select() failed");
      break;
   }
   DescRead = err;
   for (SockStorage = 0; SockStorage <= sMax && DescRead > 0; ++SockStorage)
   {
      if (FD_ISSET(SockStorage, &fduse))
      {
         DescRead -= 1;
         if (SockStorage == socketFd)
         {
            printf("  Listening socket is readable\n");
            do
            {
               NewSFD =
                  accept(socketFd, (struct sockaddr *)&cli_addr, &clilen);
               if (NewSFD < 0)
               {
                  if (errno != EWOULDBLOCK)
                  {
                     perror("  accept() failed");
                     DCSERVER = TRUE;
                  }
                  break;
               }
               if (ClientCount < MAX_CLIENTS)
               {
                  for (loop = 0; loop < MAX_CLIENTS; loop++)
                  {
                     if (Clients[loop].connected_sock < 0)
                     {
                        Clients[loop].connected_sock = NewSFD;
                        break;
                     }
                  }
                  ClientCount++;
               }
               else
               {
                  printf("Maximum Client Reached.\n");
                  char *sendtoclient = "Server full. ";
                  send(NewSFD, sendtoclient, strlen(sendtoclient), 0);
                  close(NewSFD);
                  break;
               }
               ip = ntohl(cli_addr.sin_addr.s_addr);
               printf("  Connection from %d.%d.%d.%d\n",
                  (int)(ip >> 24) & 0xff,
                  (int)(ip >> 16) & 0xff,
                  (int)(ip >> 8) & 0xff, (int)(ip >> 0) & 0xff);
               dlogs(ip);

               FD_SET(NewSFD, &fdin);
               if (NewSFD > sMax)
                  sMax = NewSFD;
            }
            while (NewSFD != -1);
         }
         else
         {
            int d;
            for (d = 0; d < MAX_CLIENTS; d++)
            {
               printf("Descriptor ID: %d\n", Clients[d].connected_sock);
            }

            pfds[0].fd = fd;
            pfds[0].events = POLLIN;
            pfds[1].fd = SockStorage;
            pfds[1].events = POLLIN;
            state = FALSE;
            do
            {
               rc = poll(pfds, 2, -1);
               if (pfds[0].revents & POLLIN)
               {
                  while ((nbytes = read(fd, buf, sizeof (buf) - 1)) > 0)
                  {
                     buf[nbytes] = '\0';
                     printf("%s\n", buf);
                  }
                  pfds[0].events = 0;
                  pfds[1].events = POLLIN | POLLOUT;
               }
               if (pfds[1].revents & POLLIN)
               {
                  err = recv(SockStorage, strbuf, sizeof (strbuf), 0);
                  if (err < 0)
                  {
                     if (errno != EWOULDBLOCK)
                     {
                        perror("  recv() failed");
                        state = TRUE;
                     }
                     break;
                  }
                  if (err == 0)
                  {
                     printf("  Connection closed\n");
                     state = TRUE;
                     break;
                  }
                  dSize = err;
                  printf("  %d bytes received\n", dSize);
               }

               if (pfds[1].revents & POLLOUT)
               {
                  int s;
                  for (s = 0; s < MAX_CLIENTS; s++)
                  {
                     if (Clients[s].connected_sock > 0)
                     {
                        err =
                           send(Clients[s].connected_sock, buf,
                           strlen(buf), 0);
                        if (err < 0)
                        {
                           perror("  send() failed");
                           track = s;
                           state = TRUE;
                           break;
                        }
                     }
                  }
                  pfds[0].events = POLLIN;
                  pfds[1].events = POLLIN;
               }

            }
            while (TRUE);
            fopen("/sockF.txt", "w");
            if (state)
            {
               ClientCount--;
               close(SockStorage);
               FD_CLR(SockStorage, &fdin);
               if (SockStorage == sMax)
               {
                  while (FD_ISSET(sMax, &fdin) == FALSE)
                     sMax -= 1;
               }
            }
         }
      }
   }
} while (DCSERVER == FALSE);
cleanUP(SockStorage, sMax);
}

私はそれを2日間取り組んでいますが、まだ取得できません。ありがとう..

4

1 に答える 1

0

さて、動作するマルチ接続デーモンの例を示すために、この例を見てください

さらに説明が必要な場合は、撃ってください。

この例のコードはdaemon_init()などを取り除いているので、やみくもにコピー&ペーストしてコンパイルしようとしてもうまくいかないことに注意してください。

setnonblocking()リクエストに応じて追加されました。

void setnonblocking(sock)
  int sock;
{
  int opts;

  opts = fcntl(sock, F_GETFL);

  if (opts < 0)
    {
      syslog(LOG_ERR, "fcntl(F_GETFL) failed");
      exit(EXIT_FAILURE);
    }

  opts = (opts | O_NONBLOCK);

  if (fcntl(sock, F_SETFL, opts) < 0)
    {
      syslog(LOG_ERR, "fcntl(F_SETFL) failed");
      exit(EXIT_FAILURE);
    }

  return;
}

daemon_init()

int daemon_init(void)
{
  pid_t pid;
  int i;


  if ((pid = fork()) < 0)
    {
      return -1;
    }
  else if (pid != 0)
    {
      exit(0);
    }

  for (i=getdtablesize();i>=0;--i) close(i);
  i = open("/dev/null", O_RDWR); /* open stdin */
  dup(i); /* stdout */
  dup(i); /* stderr */

  setsid();
  return 0;
}
于 2012-10-25T01:28:26.180 に答える