Я пытаюсь программирования сокетов и с кодом сервера:
while(1) {
sin_size = sizeof (their_addr);
new_fd = accept(sockfd,(struct sockaddr *)&their_addr, &sin_size);
if(new_fd == -1) {
perror("accept");
continue;
}
inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr*)&their_addr),s,sizeof(s));
cout<<"got connection from" << s << endl;
if((pid = fork()) == 0){//child
close(sockfd);
if(send(new_fd,"hello world!",12,0) == -1) {
perror("send");
close(new_fd);
exit(0);
}
char buf[50];
int numbytes;
if((numbytes = recv(new_fd,&buf,50,0)) == -1) {
perror("receive");
close(new_fd);
exit(0);
}
buf[numbytes] = '\0';
cout<<"numbytes" << numbytes <<endl;
cout<<"server received " << buf <<endl;
}
close(new_fd);
}
этот код дает мне плохой дескриптор файла, однако, когда я комментирую закрытие (sockfd),
код работает нормально. Поскольку я разветвляюсь на новый дочерний процесс и закрываю порт прослушивания, почему я получаю неверный дескриптор файла? Есть что-то, чего я здесь не хватает?
Вы закрываете new_fd
дважды. После того, как вы получите, вы закрываете его один раз, затем дочерний процесс продолжается и снова закрывает его. Вы должны поставить это второе close
только в родительском процессе или совсем не закрывается внутри if (fork())
тело.
Я знаю, что прошло почти 2 года с тех пор, как был поставлен вопрос, но у меня возникла та же проблема, и, поиграв в поисках и не найдя ничего, я решил попробовать над этим поработать некоторое время. Я обнаружил, что проблема заключается в том, что вы не закрываете дочерний процесс, если нет ошибки отправки. Так что вместо этого:
if (send(new_fd,"hello world!",12,0) == -1) {
perror("send");
close(new_fd);
exit(0);
}
Переместите закрывающую скобку прямо под перрором, вот так:
if (send(new_fd,"hello world!",12,0) == -1) {
perror("send");
}
close(new_fd);
exit(0);
Делая это, вы заставляете дочерний процесс закрываться сразу после отправки сообщения. Я не совсем уверен, но я думаю, что дескриптор плохого файла исходит из вызова, чтобы принять, раздвоенным дочерним процессом, который не был закрыт, но имеет дескриптор плохого файла, так как вы закрыли сокет прослушивания для этот процесс.