Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
第一次使用select(),可能是一个基本问题?_C_Sockets_Select_Client Server - Fatal编程技术网

第一次使用select(),可能是一个基本问题?

第一次使用select(),可能是一个基本问题?,c,sockets,select,client-server,C,Sockets,Select,Client Server,我已经使用select()使用此服务器工作了几天。它的作用是,我有两个客户阵列(一个是“供应商”,另一个是“消费者”),服务器的任务是检查供应商是否有东西要发送给消费者,如果有,就发送 服务器的第二部分是,当消费者收到供应商的信息时,他们会向发送信息的供应商发送确认消息 当客户机连接时,它会被识别为“未定义”,直到服务器将其放入正确的客户机阵列时,它发送一条带有“供应商”或“消费者”字样的消息(西班牙语,我来自那里) 服务器的功能在这里并不重要。重要的是,我用两个不同的“for”循环来完成这两个

我已经使用select()使用此服务器工作了几天。它的作用是,我有两个客户阵列(一个是“供应商”,另一个是“消费者”),服务器的任务是检查供应商是否有东西要发送给消费者,如果有,就发送

服务器的第二部分是,当消费者收到供应商的信息时,他们会向发送信息的供应商发送确认消息

当客户机连接时,它会被识别为“未定义”,直到服务器将其放入正确的客户机阵列时,它发送一条带有“供应商”或“消费者”字样的消息(西班牙语,我来自那里)

服务器的功能在这里并不重要。重要的是,我用两个不同的“for”循环来完成这两个部分,这就是我遇到问题的地方。当第一个用户连接到服务器(无论是供应商还是消费者)时,服务器会陷入第一个或第二个循环,而不仅仅是继续执行。因为这是我第一次使用select(),所以我可能遗漏了一些内容。你们能帮我什么忙吗

先谢谢你

for(;;)
{
    rset=allset;
    nready=select(maxfd+1,&rset,NULL,NULL,NULL);

    if (FD_ISSET(sockfd, &rset))
    {
        clilen=sizeof(cliente);
        if((connfd=accept(sockfd,(struct sockaddr *)&cliente,&clilen))<0)
        {
            printf("Error");
        }

        IP=inet_ntoa(cliente.sin_addr);
        for(i=0;i<COLA;i++)
        {
            if(indef[i]<0)
            {
                indef[i]=connfd;
                IPind[i]=IP;
                break;
            }
        }

        FD_SET(connfd,&allset);     
        if(connfd > maxfd)
        {
            maxfd=connfd;
        }
        if(i>maxii)
        {
            maxii=i;
        }
        if(--nready<=0)
        {    continue; }
    }// Fin ISSET(sockfd)

    for(i=0;i<=maxii;i++)
    {
        if((sockfd1=indef[i])<0)
        { continue; } //!

        if(FD_ISSET(sockfd1,&rset))
        {
            if((n=read(sockfd1,comp,MAXLINE))==0)
            {
                close(sockfd1);
                FD_CLR(sockfd1,&allset);
                indef[i]=-1;
                printf("Cliente indefinido desconectado \n");
            }
            else
            {
                comp[n]='\0';
                if(strcmp(comp,"suministrador")==0)
                {
                    for(j=0;j<=limite;j++)
                    {
                        if(sumi[j]<0)
                        {
                            IPsum[j]=IPind[i];
                            sumi[j]=indef[i];
                            indef[i]=-1;
                            if(j>maxis)
                            {
                                maxis=j;
                            }
                            break;
                        }
                    }
                }
                else if(strcmp(comp,"consumidor")==0)
                {
                    for(o=0;j<=limite;j++)
                    {
                        if(consum[o]<0)
                        {
                            IPcons[o]=IPind[i];
                            consum[o]=indef[i];
                            indef[o]=-1;
                            if(o>maxic)
                            {
                                maxic=o;
                            }
                            break;
                        }
                    }
                }

                if(--nready <=0)
                {
                    break;
                }
            }
        }
    }//fin bucle for maxii
    for(i=0;i<=maxis;i++)
    {
        if((sockfd2=sumi[i])<0)
        {    continue; }

        if(FD_ISSET(sockfd2,&rset))
        {
            if((n=read(sockfd2,buffer2,MAXLINE))==0)
            {
                close(sockfd2);
                FD_CLR(sockfd2,&allset);
                sumi[i]=-1;
                printf("Suministrador desconectado \n");
            }
            else
            {
                buffer2[n]='\0';
                for(j=0;j<=maxic;j++)
                {
                    if((sockfd3=consum[j])<0)
                    {    continue; }
                    else    
                    {
                        strcpy(final,IPsum[i]);
                        strcat(final,":");
                        strcat(final,buffer2);
                        write(sockfd3,final,sizeof(final));
                        respuesta[i]=1;
                    }
                }
                break; // ?
            }
        }
    }//fin for maxis

    for(i=miniic;i<=maxic;i++)
    {
        if((sockfd4=consum[i])<0)
        {    continue; }

        if(FD_ISSET(sockfd4,&rset))
        {
            if((n=read(sockfd4,buffer3,MAXLINE))==0)
            {
                close(sockfd4);
                FD_CLR(sockfd4,&allset);
                consum[i]=-1;
                printf("Consumidor desconectado \n");
            }
            else
            {
                buffer3[n]='\0';
                IP2=strtok(buffer3,":");
                obj=strtok(NULL,":");
                for(j=0;j<100;j++)
                {
                    if((strcmp(IPsum[j],IP2)==0) && (respuesta[j]==1))
                    {
                        write(sumi[j],obj,sizeof(obj));
                        miniic=i+1;
                        respuesta[j]=0;
                        break;                           
                    }
                }
            }
        }
    }
(;;)的

{
rset=allset;
nready=select(maxfd+1,&rset,NULL,NULL,NULL);
if(FD_ISSET(sockfd和rset))
{
clilen=sizeof(客户);

如果((connfd=accept(sockfd,(struct sockaddr*)&cliente,&clilen))您可以阅读介绍性文档
看看阻塞连接与非阻塞连接

您可能会阅读介绍性文章
看看阻塞连接和非阻塞连接

嗯,我认为您的逻辑完全错误。它应该看起来更像这样(警告,未测试的伪代码):

(;;)的

{
//首先,设置fd_集合,以指定要通知的套接字
fd_set readSet;fd_CLR(&readSet);
fd_set writeSet;fd_CLR(&writeSet);
int maxFD=-1;
对于(int i=0;i maxFD)maxFD=consumer_sockets[i];
FD_集(用户_套接字[i]、&readSet);
如果(消费者有数据,他希望发送[i])FD\u集(消费者套接字[i],&writeSet);
}
对于(int i=0;i maxFD)maxFD=producer_sockets[i];
FD_集(生产者_套接字[i],&readSet);
如果(producer_有数据,他想发送[i])FD_集(producer_sockets[i],&writeSet);
}
//现在我们阻塞select(),直到有东西准备好在套接字上处理为止
int selResult=select(maxFD+1,&readSet,&writeSet,NULL,NULL);
如果(selResult<0){perror(“select”);退出(10);}

对于(int i=0;iHmm),我认为您的逻辑完全错误。它应该看起来更像这样(警告,未测试的伪代码):

(;;)的

{
//首先,设置fd_集合,以指定要通知的套接字
fd_set readSet;fd_CLR(&readSet);
fd_set writeSet;fd_CLR(&writeSet);
int maxFD=-1;
对于(int i=0;i maxFD)maxFD=consumer_sockets[i];
FD_集(用户_套接字[i]、&readSet);
如果(消费者有数据,他希望发送[i])FD\u集(消费者套接字[i],&writeSet);
}
对于(int i=0;i maxFD)maxFD=producer_sockets[i];
FD_集(生产者_套接字[i],&readSet);
如果(producer_有数据,他想发送[i])FD_集(producer_sockets[i],&writeSet);
}
//现在我们阻塞select(),直到有东西准备好在套接字上处理为止
int selResult=select(maxFD+1,&readSet,&writeSet,NULL,NULL);
如果(selResult<0){perror(“select”);退出(10);}

对于(int i=0;i),您的代码格式非常糟糕。有很多额外的空行。有时{-方括号与控制语句位于同一行,有时不在同一行。有时根本没有方括号。改进编程的第一个方法是应用一致的格式。我已根据更普遍接受的布局重新格式化了代码。您的代码格式很差。有很多额外的空行。有时{-方括号与控制语句位于同一行,有时不在同一行。有时根本没有方括号。改进编程的第一个方法是应用一致的格式。我已根据更普遍接受的布局重新格式化了代码。对于格式不好,我很抱歉。我尝试做的第一件事是使用send()和recv()而不是read()和write(),但仍然不太管用。无论如何,感谢您的回复。我为糟糕的格式设置感到抱歉。我尝试做的第一件事是使用send()和recv()而不是read()和write(),但仍然不太管用。不管怎样,谢谢你的回复。非常感谢你的回答。看到你几天的工作都被扔进垃圾箱,这有点令人沮丧,但知道真相很好。这是一个遗憾,因为在执行服务器时,我真的很快就要完成了。你的小例子会改变吗如果我使用read()、write()和blocking sockets会怎么样?这是大学作业,我们从来没有使用过非阻塞socket或非阻塞i/O。这对我来说都是新鲜事,而且截止日期不远了。无论如何,在Linux/Unix上,recv()/read()和write()/send()是等价的(至少在网络套接字上使用时是如此)。至于使用阻塞套接字/IO,您可以尝试一下,但这很棘手,因为如果您尝试在没有数据准备好读取的套接字上读取()/recv(),那么read()/recv()将在网络到达更多字节之前不会返回…这可能需要很长时间,也可能永远不会,同时,所有其他套接字I/O都会被阻塞。(如果远程客户端拒绝读取其传入数据,则send()/write()阻塞也会出现类似的问题,但问题并没有那么大)。非常感谢您的回答。看到您几天来的工作方式被扔进垃圾箱有点令人沮丧,但知道真相很好。这是一个遗憾,因为在执行服务器时,我似乎真的快完成了。如果我使用read()、write()和blocking sockets,您的小示例会有很大变化吗?这是coll
for (;;)
{
   // First, set up the fd_sets to specify the sockets we want to be notified about
   fd_set readSet;  FD_CLR(&readSet);
   fd_set writeSet; FD_CLR(&writeSet);
   int maxFD = -1;
   for (int i=0; i<num_consumers; i++)
   {
      if (consumer_sockets[i] > maxFD) maxFD = consumer_sockets[i];
      FD_SET(consumer_sockets[i], &readSet);
      if (consumer_has_data_he_wants_to_send[i]) FD_SET(consumer_sockets[i], &writeSet);
   }
   for (int i=0; i<num_producers; i++)
   {
      if (producer_sockets[i] > maxFD) maxFD = producer_sockets[i];
      FD_SET(producer_sockets[i], &readSet);
      if (producer_has_data_he_wants_to_send[i]) FD_SET(producer_sockets[i], &writeSet);
   }

   // Now we block in select() until something is ready to be handled on a socket
   int selResult = select(maxFD+1, &readSet, &writeSet, NULL, NULL);
   if (selResult < 0) {perror("select"); exit(10);}

   for (int i=0; i<num_consumers; i++)
   {
      if (FD_ISSET(consumer_sockets[i], &readSet)
      {
         // There is some incoming data ready to be read from consumer_socket[i], so recv() it now
         [...]
      }
      if (FD_ISSET(consumer_sockets[i], &writeSet)
      {
         // There is buffer space in consumer_socket[i] to hold more outgoing
         // data for consumer_socket[i], so send() it now
         [...]
      }
   }
   for (int i=0; i<num_producers; i++)
   {
      if (FD_ISSET(&producer_sockets[i], &readSet)
      {
         // There is some data ready to be read from producer_socket[i], so recv() it now
         [...]
      }
      if (FD_ISSET(producer_sockets[i], &writeSet)
      {
         // There is buffer space in producer_socket[i] to hold more outgoing
         // data for producer_socket[i], so send() it now
         [...]
      }
   }
}