2012-10-24 28 views
0

我有客户端可以连接到的此服务器应用程序。现在我希望当客户端连接时,我可以发送数据给他们。当我连接我的两个客户端时,我设法做到这一点..我发送的是我的两个客户端收到的。但我的问题是当我连接客户端1然后发送数据到服务器,客户端1可以接收数据,然后我连接客户端2,我发送数据到服务器。现在当我从服务器发送数据到我的客户端时,只有客户端1可以接收数据,但是当我断开客户端1时,客户端2可以从服务器接收数据。将数据发送到我的服务器上连接的多个客户端

我怎样才能让他们在同一时间工作?..而且我怎样才能让我的服务器从我的客户接受的同时消息?..

这里是有码IM麻烦的一部分。

for(j=0;j<MAX_CLIENTS; j++) 
Clients[j].connected_sock = -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"); 


       state = TRUE; 

       break; 
       } 

       } 

      } 
      pfds[0].events = POLLIN; 
      pfds[1].events = POLLIN; 
      } 


      } while (TRUE); 

下面是如何发送数据给我的客户。

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"); 


       state = TRUE; 

       break; 
       } 

       } 

      } 

感谢,

+1

为每个socket连接 – mathematician1975

+0

你的意思是,每接受一个单独的线程? – demic0de

+0

是的,你应该有一个单独的线程,每个接受。你可以阅读'pthread'库。 – Raj

回答

0

通常有几个可能的解决方案:

  1. 您可以使用单独的线程为每个客户端连接;
  2. 您可以使用select;
  3. 您可以使用民意调查;
  4. 你可以使用epoll;

在Windows环境下,也有一些其他的可能性,例如IOCP例如。

上述每种解决方案都有一些优缺点(您通常需要区分简单性和性能)。

你可以阅读一些网络编程教程的详细信息,例如this

+0

我已阅读关于libev。我可以使用它吗? – demic0de

+0

经过一些简单的检查后,您似乎可以将其用于您的目的。不过,如果你打算只与几个客户端连接,你可以检查一些“简单选择”的例子。 – codewarrior

+0

是的,谢谢你,我设法使它与选择循环一起工作。非常感谢 – demic0de

相关问题