套接字描述符在赋值后关闭

时间:2014-03-05 05:17:01

标签: c++ sockets

我不会发布所有通用套接字代码 - 除非请求,否则没问题。

我在已设置的套接字上侦听连接:

int
NetworkConnection::ListenForConnections()
{
    char s[INET6_ADDRSTRLEN];
    fcntl(socketFd, F_SETFL, O_NONBLOCK);

    if (listen(socketFd, 15) == -1) {
        perror("listen");
        exit(1);
    }

//    sigAction.sa_handler = sigchld_handler; // reap all dead processes    
//    sigemptyset(&sigAction.sa_mask);
//    sigAction.sa_flags = SA_RESTART;

    if (sigaction(SIGCHLD, &sigAction, NULL) == -1) {
        perror("sigaction");
        exit(1);
    }

    printf("server: waiting for connections...\n");


        sin_size = sizeof theirAddress;
        int new_fd = accept(socketFd, (struct sockaddr *)&theirAddress, &sin_size);
        if (new_fd == -1) {
            perror("accept");
            return 1;
        }

        inet_ntop(theirAddress.ss_family,
            get_in_addr((struct sockaddr *)&theirAddress),
            s, sizeof s);
        printf("server: got connection from %s\n", s);


            NodeConnection nc = NodeConnection();

            char ipstr[INET6_ADDRSTRLEN];
            getpeername(new_fd, (struct sockaddr*)&theirAddress, &sin_size);
            struct sockaddr_in *soc = (struct sockaddr_in *)&theirAddress;
            int port = ntohs(soc->sin_port);
            inet_ntop(AF_INET, &soc->sin_addr, nc.ipstr, sizeof ipstr);

            nc.fd = new_fd;
            nc.theirAddress = sockaddr_storage(theirAddress);
            nc.sin_size = sin_size;
            nc.port = port;
            newConnections.push_back(nc);

}

这是从这里调用的:

int main(int argc, const char* argv[])
{
    RoutingManager *manager = new RoutingManager();
    manager->ParseInputFile("topo.txt", 10, 3, " ");

    manager->myConnection = new NetworkConnection("localhost", "7771");
    manager->myConnection->SetSocketHints();
    manager->myConnection->PopulateAddressInfo();
    manager->myConnection->BindSocket();

    while(1)
    {
        manager->myConnection->ListenForConnections();  // <- here
        if (manager->myConnection->newConnections.size() > 0)
        {
            manager->ActivateNewNode();
        }

    }
}

在致电ActivateNewNode()期间,我做了:

bool
RoutingManager::ActivateNewNode()
{
    TopologyIter iter = topology.begin();
    do
    {
        if(!iter->second.online)
        {
            iter->second.online = true;
            iter->second.connection = myConnection->newConnections.back();
            myConnection->newConnections.pop_back();

            cout << "Connected Activated!\n";
            cout << "Node ID: " << iter->second.id << endl;
            return true; //all good
        }

        iter++;

    }while (iter != topology.end());

    return false; //received a connection, but no more nodes to hand out
}

connection是结构:

struct NodeConnection
{
    int fd;
    socklen_t sin_size;
    struct sockaddr_storage theirAddress; 
    char ipstr[INET6_ADDRSTRLEN];
    int port;
};

如果我在调用ActivateNewNode()期间注释掉连接的分配,这可以正常工作。即,这一行:

iter->second.connection = myConnection->newConnections.back();

但是,如果没有注释,那么当我循环回来继续侦听新连接时,此代码段会失败:

if (listen(socketFd, 15) == -1) {
        perror("listen");
        exit(1);
    }

错误:bad file descriptor 谁能告诉我我在这里缺少什么?

1 个答案:

答案 0 :(得分:1)

listen()放出while循环。