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 }
У меня есть вопрос об исходном коде выше, который приведен в примере моей книги. Моя проблема в том, что есть клиенты, которые подключены к серверу.что-то запутанное в отношении использования функции select
В этой ситуации (есть некоторые клиенты) другой плохой клиент отправляет SYN-пакет (не отвечают на сервер SYN/ACK-пакет) на сервер, поэтому функция select возвращает сообщение отправленное serv_sock. Наконец, из-за этого сервер вызовет функцию Accept()
. Но он заблокирован от функции Accept()
, потому что это незавершенный запрос на соединение (контраст с завершенным запросом на соединение, который выполняется с помощью трехстороннего рукопожатия).
Итак, здесь сервер заблокирован от Accept()
функции. В этой ситуации клиент отправляет сообщение серверу. Сервер не может вызвать функцию read()
, потому что она заблокирована от Accept()
функции.
Что я пишу выше, правильно ???