У меня есть некоторая путаница по поводу того, как сокет fd и fd_set изменились на FD_ISSET и как FD_ISSET может проверить это сокет fd , включая fd_set . Итак, я сделал небольшой тест.
int sock_fd = -1;
fd_set read_set;
while (sock_fd < 20)
{
printf("Init: sock_fd is %d, read_set is %ld\n", sock_fd, read_set);
FD_ZERO(&read_set);
printf("after FD_ZERO sock_fd is %d, read_set is %ld\n", sock_fd, read_set);
FD_SET(sock_fd, &read_set);
printf("after FD_SET sock_fd is %d, read_set is %ld\n", sock_fd, read_set);
FD_ISSET(sock_fd, &read_set);
printf("after FD_ISSET sock_fd is %d, read_set is %ld\n", sock_fd, read_set);
FD_CLR(sock_fd, &read_set);
printf("after FD_CLR sock_fd is %d, read_set is %ld\n", sock_fd, read_set);
printf("***********************************\n");
sock_fd++;
}
Это мой код. Регулярность очевидна. Для каждой пары значение read_set является значением sock_fd + 63, то есть read_set = sock_fd + 63 . Исходя из этого, я могу сказать, что исходное значение read_set составляет 63 (111111) . Но я не знаю почему. Итак, я решил сделать следующий тест. Я добавил немного printf в мою прошлую демонстрацию. Это часть этого кода.
fd_set read_set;
fd_set write_set;
fd_set select_read_set;
FD_ZERO(&read_set);
FD_ZERO(&write_set);
FD_ZERO(&select_read_set);
printf("after FD_ZERO, read_set is %ld, write_set is %ld, select is %ld\n", read_set, write_set, select_read_set);
for (i = 0; i < MAX_CLIENT_NUM; i++)
{
client_fd[i] = -1;
}
memset(&serv_addr, 0, sizeof(serv_addr));
memset(&cli_addr, 0, sizeof(cli_addr));
printf("111 sock_fd is %d, read_set is %ld, write_set is %ld, select is %ld\n", read_set, write_set, select_read_set);
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
printf("sock_fd is %d\n", sock_fd);
if (sock_fd < 0)
{
perror("Fail to socket");
exit(1);
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERVER_PORT);
serv_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
printf("222 sock_fd is %d, read_set is %ld, write_set is %ld, select is %ld\n", read_set, write_set, select_read_set);
unsigned int value = 1;
if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (void *)&value, sizeof(value)) < 0)
{
perror("Fail to setsockopt");
exit(1);
}
printf("333 sock_fd is %d, read_set is %ld, write_set is %ld, select is %ld\n", read_set, write_set, select_read_set);
serv_addr_len = sizeof(serv_addr);
if (bind(sock_fd, (struct sockaddr*)&serv_addr, serv_addr_len) < 0)
{
perror("Fail to bind");
exit(1);
}
if (listen(sock_fd, BACK_LOG) < 0)
{
perror("Fail to listen");
exit(1);
}
char buf[1024];
//max_fd = sock_fd;
printf("PPP sock_fd is %d, read_set is %ld, write_set is %ld, select is %ld\n", read_set, write_set, select_read_set);
FD_SET(sock_fd, &read_set);
printf("QQQ sock_fd is %d, read_set is %ld, write_set is %ld, select is %ld\n", read_set, write_set, select_read_set);
Результат меня совершенно смущает. Это приговор напечатан на экране.
after FD_ZERO, read_set is 31834128, write_set is 0, select is 0
111 sock_fd is -404688640, read_set is 16, write_set is 2147483583, select is 0
sock_fd is 3
222 sock_fd is 0, read_set is 140083558421840, write_set is -104, select is 1844674407370955161
333 sock_fd is 1, read_set is 2, write_set is 140083557848394, select is 4
PPP sock_fd is 20, read_set is 16, write_set is 140083557847575, select is 0
QQQ sock_fd is 0, read_set is 8, write_set is 3, select is 0
Я не могу их понять. Посмотрите мой код, я ничего не делал для read_set после FD_ZERO до FD_SET, но read_set всегда менялся. И даже я никогда ничего не делаю для write_set , select_read_set эти два fd_set, они изменились. Я понятия не имею об этих четырех вопросах: 1. Как FD_ISSET оценивает fd , содержащиеся в fd_set ? 2. Для этих двух тестов, почему результат их? Я описал свое замешательство. 3. Что касается второго теста, вы можете видеть, что значение 'sock_fd' также может быть изменено. Я думаю, это должно быть изменено bind()
и другими функциями. Но я не понимаю, почему сокет fd нужно изменить? Исходя из моих мыслей, один сокет fd уникален для сокета, и этот будет сохраняться до закрытия. 4. Является ли возвращаемое значение socket()
(сокет fd) случайным? Я не могу найти какую-то регулярность этого.
Пожалуйста, научите меня или дайте мне несколько советов. Спасибо