2015-04-01 3 views
1

Я не мог найти дубликат, поэтому решил опубликовать. Теперь мы получаем в Sockets (начальный уровень) и получили код ниже, чтобы клиент послал простое сообщение на сервер с помощью send() и recv(). Тем не менее, все, что я пробовал, похоже, не избавляет от error: Bad File Descriptor, а newsockfd всегда возвращает значение -1. Я смущен и понятия не имею, почему это не работает.Linux Socket Bad File Descriptor

defs.h

#include <stdio.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 

#define SERV_TCP_PORT 6000 
#define SERV_HOST_ADDR "127.0.0.1" 

char *pname; 

client.c

#include "../defs.h" 
#include <stdio.h> 
#include <stdlib.h> 
#include <strings.h> 

main(argc, argv) 
int argc; 
char *argv[]; 
{ 
    int sockfd; 
    struct sockaddr_in serv_addr; 

    pname=argv[0]; 
    bzero((char*) &serv_addr, sizeof(serv_addr)); 
    serv_addr.sin_family=AF_INET; 
    serv_addr.sin_addr.s_addr=inet_addr(SERV_HOST_ADDR); 
    serv_addr.sin_port=htons(SERV_TCP_PORT); 
    if((sockfd=socket(AF_INET,SOCK_STREAM,0)) < 0) { 
    printf("client: can't open stream socket\n"); 
    exit(0); 
    } 
    if (connect(sockfd,(struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { 
    printf("client: can't connect to server\n"); 
    exit(0); 
    } 
send(sockfd,"1",1,0); 
    close(sockfd); 
    exit(0); 
} 

server.c

#include "../defs.h" 
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/socket.h> 
#include <strings.h> 
void error(char *msg) 
{ 
    perror(msg); 
    exit(1); 
} 
main(argc, argv) 
int argc; 
char *argv[]; 
{ 
    int sockfd,clilen, childpid; 
int newsockfd; 
char buff[255]; 
    struct sockaddr_in cli_addr, serv_addr; 
    if ((sockfd=socket(AF_INET,SOCK_STREAM, 0)) <0) { 
    printf("server: can't open stream socket\n"); 
    exit(0); 
    } 
    bzero((char*) &serv_addr, sizeof(serv_addr)); 
    serv_addr.sin_family=AF_INET; 
    serv_addr.sin_addr.s_addr=htonl(INADDR_ANY); 
    serv_addr.sin_port=htons(SERV_TCP_PORT); 

    if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { 
    printf("server: can't bind local address\n"); 
    exit(0); 
    } 
    listen(sockfd, 5); 
    for (; ;) { 
    clilen=sizeof(cli_addr); 
    newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); 
    printf("%d\n",newsockfd); 
    if(newsockfd < 0) { 
     printf("server: accept error\n"); 
    error("ERROR on accept"); 
     exit(0); 
    } 
    if((childpid=fork()) <0) { 
     printf("server: fork error\n"); 
     exit(0); 
    } 
    else if (childpid==0) { 
     close(sockfd); 
     recv(newsockfd,buff,sizeof(buff),0); 
    } 
    close(newsockfd); 
    } 
} 

Спасибо за ваше время.

+0

Первое, что нужно сделать, это распечатать дополнительную информацию об ошибке. В Linux последняя ошибка сохраняется в значении «errno». Распечатайте это и посмотрите, что означает значение. Или используйте функцию «perror», чтобы распечатать строковое сообщение, соответствующее ошибке. – kaylum

+0

Функция perror возвращала ERROR на accept, Bad File Descriptor, но Корлук объяснил мою ошибку. – DominusMors

ответ

2

В коде ребенка вы закрытьsockfd, который представляет сервер. Но в следующей итерации бесконечного цикла for, петли , который также запускает, вы делаете accept() новым клиентом с использованиемsockfd. Поэтому sockfd является Bad file descriptor.

Удалите строку close(sockfd); в своем коде и закройте его, когда сможете быть абсолютно уверены, что он больше не нужен.

+1

Большое вам спасибо, я был так напуган этим кодом. И спасибо за объяснение, которое помогло мне это понять! – DominusMors

Смежные вопросы