Linux套接字坏文件描述符

6
我没有找到重复的内容,所以决定进行发布。我们现在开始进入套接字(初学级别)领域,被要求使用send()recv()函数编写下面的代码,使客户端向服务器发送一条简单消息。然而,不管我尝试了什么,都无法摆脱错误:坏文件描述符,并且newsockfd总是返回值-1。我很困惑,也不知道为什么会出现这种情况。 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);
  }
}

感谢您的时间。

首先要做的是打印出关于错误的更多细节。在 Linux 中,最后一个错误被存储在 "errno" 值中。打印出它并查找该值的含义。或者使用 "perror" 函数打印出与错误对应的字符串消息。 - kaylum
perror函数在accept时返回了ERROR,Bad File Descriptor,但是Corluk解释了我的错误。 - DominusMors
1个回答

4
在子代码中,您关闭代表服务器的sockfd。但是,在无限for循环的下一次迭代中,也在子进程中运行,您尝试使用sockfd 接受新客户端。因此,sockfd是一个坏文件描述符
在您的代码中删除close(sockfd);行,并在您确信不再需要它时关闭它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接