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()
函數。
我上面寫的是正確的嗎?