2016-02-26 49 views
0
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()函數。但是由於它沒有完成連接請求(與由3way握手完成的完成的連接請求形成對比),因此它被阻止在Accept()函數中。

因此,在這裏,服務器被阻止從Accept()函數。在這種情況下,當客戶端發送消息到服務器。服務器不能調用read()函數,因爲它的功能被阻塞了Accept()函數。

我上面寫的是正確的嗎?

回答

1

我的問題是當有客戶端連接到服務器。

不,它不是。您的問題與連接到服務器的客戶端無關。這是關於客戶端無法完成到服務器的連接。

在這種情況下(有一些客戶端),另一種不好的客戶端發送SYN包(不回覆服務器的SYN/ACK數據包)到服務器,serv_sock如此選擇函數返回發送的消息。

不,它不。你做到了。當積壓隊列上存在完整的連接時它會返回。您的示例不是完整的連接,並且不是觸發的候選人select().

最後,因爲這個原因,服務器將調用Accept()函數。

號它仍然會被阻止在select().

但它從accept()函數阻塞,因爲它是未完成的連接請求(對比的是由三通握手完成完成連接請求)。

不,它被阻止在select(),因此。

所以,在這裏,服務器被阻止接受()函數。

在這種情況下,當客戶端發送消息給服務器。服務器無法調用read()函數,因爲它阻止了Accept()函數。

No.

我上面寫的是對的?