Я пытаюсь написать простое приложение чата, в котором клиент получает строку с сервера и отправляет новое сообщение, которое будет доставлено к следующему подключению клиента. Я новичок в программировании сокетов, и я действительно не могу понять, почему эта ошибка возникает. После того, как клиент отправляет свой буфер, сервер уведомляет об ошибке accept()
(возврат -1) и деструктор файла. Вот код, работающий на сервере:bad file descriptor: error on accept()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
void error(char *msg) {
perror(msg);
exit(1);
}
int main (int argc, char *argv[]) {
if (argc < 2) {
error("ERROR, no port provided\n");
}
int sockfd;
struct sockaddr_in serv_addr, cli_addr;
int cli_len, portno;
char message[256];
pid_t pid;
int n;
portno = atoi(argv[1]);
bzero((char*)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
n = bind (sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
if (n < 0) {
error("ERROR on binding\n");
}
listen(sockfd, 5);
do {
cli_len = sizeof(cli_addr);
int newsockfd;
newsockfd = accept(sockfd,(struct sockaddr*)&cli_addr,(socklen_t *)&cli_len);
if (newsockfd < 0) {
printf("%i", newsockfd);
error("ERROR on accept\n");
}
pid = fork();
if(pid == 0) {
close(sockfd);
sockfd = -1;
n = send(newsockfd, message, strlen(message), 0);
if (n < 0) error("ERROR sending\n");
bzero(message, 256);
n = recv(newsockfd, message, 256, 0);
if (n < 0) error("ERROR receiving\n");
close(newsockfd);
newsockfd = -1;
}
}
while(1);
return 0;
}
cli_len должно быть типа socklen_t, а не int. Привилегия скрывает потенциальную проблему на x86_64, где int может быть 32 бит, но другие типы size_related могут быть 64 бит. –
Вы неправильно сообщаете об ошибке. Вам нужно вызвать 'perror()' или 'strerror()' * перед тем, как сделать что-то еще, что может изменить 'errno', например' printf() '. Fix, retest, ... – EJP
Задача 2, ребенок должен вызывать exit, когда закончите, иначе оба ребенка и родитель будут сражаться в accept() ;-) –