接受错误:错误的文件描述符

时间:2017-11-20 10:53:55

标签: c++ c linux

编辑:最小,完整和可验证的示例在评论较低且代码实际工作,问题在不同的区域。抱歉发布不好,我现在无法将其删除。

我知道,有一些关于这个的网页,但我真的尝试了一切,没有任何作用。我一直有这个错误,我的代码看起来像这样:

int server_socket, new_socket;
struct sockaddr_in server;
bzero((char *) &server, sizeof(server));

server_socket = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
if(server_socket < 0) error("ERROR opening socket");

server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(port_number);

if(bind(server_socket, (struct sockaddr *) &server, sizeof(struct sockaddr_in)) < 0) error("ERROR on binding");

if(listen(server_socket, 5) < 0) error("Failed to listen for connections.");

while(1)
{
  struct sockaddr_in client;
  unsigned int client_len = sizeof(struct sockaddr_in);
  bzero((char *) &client, client_len); 

  if((new_socket = accept(server_socket, (struct sockaddr *) &client, &client_len)) < 0) 
  {
    if(errno == EAGAIN) continue;
    else error("ERROR on accept");
  }

  if((pid = fork()) > 0)
  {  // this is parent process
      close(new_socket);
  }

  else if(pid == 0)
  {  // this is a child process that will handle an incoming request
    long_pid = (long) getpid();   // current child's PID
    close(server_socket);  
    server_socket = -1;       //closing parent socket
    printf("A new connection accepted from blablabla, port %d by process %ld\n", port_number, long_pid);

   // ---- doing some staff, running the program
EDIT: while((msg_size = read(new_socket, received_data, BUFFER_SIZE)) >0)
  //  ---- when Im done:
      printf("closing newsock\n");
      close(new_socket);  // close the new socket
      new_socket = -1;
      exit(0);
    }
  }
  else error("fork() failed");
}

// close the server 
printf("closing an original socket\n");
close(server_socket);  // close an original server socket 
return 0;
}

之前,当我使用非阻塞套接字时,我没有遇到此问题。所以问题可能与它们有关。

1 个答案:

答案 0 :(得分:2)

如果我填写空白以使其成为可编辑的示例(请在下次发布mcve

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include <errno.h>
#include <arpa/inet.h>

#define port_number 2222
void error(char const *Msg)
{
    perror(Msg);
    exit(1);
}
int main()
{
    pid_t pid; long long_pid;
    int server_socket, new_socket;
    struct sockaddr_in server;
    bzero((char *) &server, sizeof(server));

    server_socket = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
    if(server_socket < 0) error("ERROR opening socket");

    server.sin_family = AF_INET;
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    server.sin_port = htons(port_number);

    if(bind(server_socket, (struct sockaddr *) &server, sizeof(struct sockaddr_in)) < 0) error("ERROR on binding");

    if(listen(server_socket, 5) < 0) error("Failed to listen for connections.");

    while(1)
    {
      struct sockaddr_in client;
      unsigned int client_len = sizeof(struct sockaddr_in);
      bzero((char *) &client, client_len); 

      if((new_socket = accept(server_socket, (struct sockaddr *) &client, &client_len)) < 0) 
      {
        if(errno == EAGAIN) continue;
        else error("ERROR on accept");
      }

      if((pid = fork()) > 0)
      {  // this is parent process
          close(new_socket);
      }

      else if(pid == 0)
      {  // this is a child process that will handle an incoming request
        long_pid = (long) getpid();   // current child's PID
        close(server_socket);  
        server_socket = -1;       //closing parent socket
        printf("A new connection accepted from blablabla, port %d by process %ld\n", port_number, long_pid);

//      ---- doing some staff, running the program
//      ---- when Im done:
          printf("closing newsock\n");
          close(new_socket);  // close the new socket
          new_socket = -1;
          _exit(0);
      }
      else error("fork() failed");
    }

    // close the server 
    printf("closing an original socket\n");
    close(server_socket);  // close an original server socket 
    return 0;
}

似乎没有任何问题。

显然,您正在使用父进程中的错误检查建立侦听套接字,然后父进程不会对关闭它的侦听套接字执行任何操作,因此您不应该从父进程获取该错误。

我的猜测是你可能错误地继续了孩子的循环(在你没有展示的部分)。