【问题标题】:something confusing about select function's usage选择函数的用法令人困惑
【发布时间】:2016-02-28 02:44:17
【问题描述】:
  1 #include "mynet.h"
  2 #include <sys/select.h>
  3 #include <sys/time.h>
  4 
  5 #define BUF_SIZE 100
  6 
  7 int main(int argc, char** argv)
  8 {
  9         int serv_sock, cli_sock;
 10         struct sockaddr_in serv_addr, cli_addr;
 11         struct timeval timeout;
 12         fd_set reads, cpy-reads;
 13 
 14         socklen_t cli_addr_size;
 15 
 16         int fd_max, str_len, fd_num, i;
 17 
 18         char buf[BUF_SIZE];
 19 
 20         if(argc!=2)
 21         {
 22                 printf("Usage: %s <port>\n", argv[0]);
 23                 exit(1);
 24         }
 25 
 26         serv_sock=Socket(PF_INET, SOCK_STREAM, 0);
 27 
 28         memset(&serv_addr, 0, sizeof(serv_addr));
 29 
 30         serv_addr.sin_family=AF_INET
 31         serv_addr.sin_port=htons(atoi(argv[1]));
 32         serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
 33 
 34         Bind(serv_sock, (sa*)&serv_addr, sizeof(serv_addr));
 35 
 36         Listen(serv_sock, 5);
 37 
 38         FD_ZERO(&reads);
 39         FD_SET(serv_sock, &reads);
 40         fd_max=serv_sock;
 41 
 42         while(1)
 43         {
 44                 cpy_reads=reads;
 45                 timeout.tv_sec=5;
 46                 timeout.tv_usec=5000;
 47 
 48                 if((fd_num=select(fd_max+1, &cpy_reads, 0, 0, &timeout))==-1)
 49                         break;
 50                 if(fd_num==0)
 51                         continue;
 52 
 53                 for(i=0; i<fd_max+1; i++)
 54                 {
 55                         if(FD_ISSET(i, &cpy_reads))
 56                         {
 57                                 if(i==serv_sock)
 58                                 {
 59                                         cli_addr_size=sizeof(cli_addr);
 60                                         cli_sock=Accept(serv_sock, (sa*)&cli_addr, &cli_addr_size);
 61                                         FD_SET(cli_sock, &reads);
 62 
 63                                         if(fd_max<cli_sock)
 64                                                 fd_max=cli_sock;
 65                                         printf("connected client: %d \n", cli_sock);
 66                                 }
 67                                 else
 68                                 {
 69                                         str_len=read(i, buf, BUF_SIZE);
 70                                         if(str_len==0)
 71                                         {
 72                                                 FD_CLR(i, &reads);
 73                                                 close(i);
 74                                                 printf("closed client: %d \n", i);
 75                                         }
 76                                         else
 77                                                 write(i, buf, str_len);
 78                                 }
 79                         }
 80                 }
 81         }
 82 
 83         close(serv_sock);
 84 
 85         return 0;
 86 }

我对上述源代码有疑问,这在我的书中的示例中。 我的问题是当有客户端连接到服务器时。

在这种情况下(有一些客户端),另一个坏客户端向服务器发送SYN包(不回复服务器的SYN/ACK包),所以select函数返回关于serv_sock的发送消息。最后,正因为如此,服务器将调用Accept() 函数。但它被Accept() 函数阻止了,因为它是未完成的连接请求(与通过3次握手完成的连接请求形成对比)。

所以,在这里,服务器被 Accept() 功能阻止。在这种情况下,当客户端向服务器发送消息时。服务器无法调用read() 函数,因为它被Accept() 函数阻止了。

我上面写的是对的???

【问题讨论】:

    标签: sockets networking


    【解决方案1】:

    我的问题是当有客户端连接到服务器时。

    不,不是。您的问题与连接到服务器的客户端无关。它是关于未能完成与服务器的连接的客户端。

    在这种情况下(有一些客户端),另一个坏客户端向服务器发送SYN包(不回复服务器的SYN/ACK包),所以select函数返回关于serv_sock的发送消息。

    不,它没有。这是你编的。当积压队列上存在完整连接时,它将返回。你的例子不是一个完整的连接,也不是触发select().的候选对象

    最后,正因为如此,服务器才会调用 Accept() 函数。

    没有。还是会在select().被屏蔽

    但它被 Accept() 函数阻止,因为它是未完成的连接请求(与通过 3way 握手完成的连接请求形成对比)。

    不,因为这个原因,它在 select() 中被屏蔽了。

    所以,在这里,服务器被 Accept() 函数阻止了。

    没有。

    在这种情况下,当客户端向服务器发送消息时。服务器无法调用 read() 函数,因为它被 Accept() 函数阻止了。

    没有。

    我上面写的对吗?

    没有。

    【讨论】:

      猜你喜欢
      • 2021-06-13
      • 2014-10-17
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 2022-01-17
      • 2018-02-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多