Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 尝试保存到成员向量的连接-一次只保存一个_C++_Multithreading_Sockets_Ubuntu_Multiprocessing - Fatal编程技术网

C++ 尝试保存到成员向量的连接-一次只保存一个

C++ 尝试保存到成员向量的连接-一次只保存一个,c++,multithreading,sockets,ubuntu,multiprocessing,C++,Multithreading,Sockets,Ubuntu,Multiprocessing,我正在尝试编写一个简单的服务器应用程序,它可以从多个客户机获取连接,并将这些连接保存到一个向量中,以供另一个对象读取 我有一个类,NetworkConnection,它是另一个类的成员,Manager。以下是我的主要方法: int main(int argc, const char* argv[]) { RoutingManager *manager = new RoutingManager(); manager->ParseInputFile("topo.txt", 10

我正在尝试编写一个简单的服务器应用程序,它可以从多个客户机获取连接,并将这些连接保存到一个向量中,以供另一个对象读取

我有一个类,
NetworkConnection
,它是另一个类的成员,
Manager
。以下是我的主要方法:

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

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

    return 0;
}
我省略了很多细节,因为它们非常类似于您可以在任何地方找到的通用套接字编程指南。。。主要问题是在通话期间:

int
NetworkConnection::ListenForConnections()
{
    char s[INET6_ADDRSTRLEN];

    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");

    while(1) {  // main accept() loop
        sin_size = sizeof theirAddress;
        int new_fd = accept(socketFd, (struct sockaddr *)&theirAddress, &sin_size);
        if (new_fd == -1) {
            perror("accept");
            continue;
        }

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

        if (!fork()) { // this is the child process
            close(socketFd); // child doesn't need the listener

            NodeConnection nc = NodeConnection();

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

            nc.fd = new_fd;
            nc.theirAddress = theirAddress;
            nc.sin_size = sin_size;
            nc.port = port;

            newConnections.push_back(nc);
            for(vector<NodeConnection>::iterator it = newConnections.begin(); it != newConnections.end(); ++it)
            {                
                cout << "Socket ID: " << it->fd << endl;
                cout << "Their Address: " << it->ipstr << endl;
                cout << "Their Port: " << it->port << endl;
                cout << "My Size: " << newConnections.size() << endl;
                cout << "**************\n";
                //cout << "Their Port: " << (int)ntohs(it->theirAddress.sin_port) << endl;
            }
            exit(0);
        }
       // close(new_fd);  // parent doesn't need this
    }
}


我可能不完全理解如何保存断开连接的数据。。因此,如果我用了错误的方法,请告诉我。

在调用fork()之后,您正在子进程中将连接详细信息推送到向量上

fork()创建一个全新的进程,它不与父进程共享任何内存。子项开始时是父项的相同副本,但对子项中变量所做的更改在父项中不可见,反之亦然

所以你的顺序是:

  • 父节点接受连接并创建子节点
  • 子节点将连接数据添加到其向量(该向量为空)
  • 子打印向量(现在包含一个条目)
  • 子对象退出(它的向量副本现在已不存在)
  • 重复步骤1中的下一个连接
  • 如果希望保留此连接数据,则需要将其添加到父进程中的向量中


    我注意到您将问题标记为“多线程”——这可能解释了混淆,因为您的程序不是多线程的,而是多进程的。同一进程中的多个线程确实共享内存。不过,我并不建议您改用线程——这会带来一整套您可能不需要的其他问题。

    很好的解释;谢谢我不知道如何监听新的连接,同时使它们对父线程可用?这不可能吗?它不是父线程,而是父进程!在这种服务器的大多数示例中,父进程不需要连接,而是由子进程处理。父级需要它做什么?这是一个持久性连接——因此,我们的想法是让一个类处理所有获取/读取新连接的操作,然后使这些连接可供启动侦听器的类使用。然后,
    管理器
    类可以定期轮询newConnections向量以获取详细信息。您不必为了接受连接而进行分叉。您可以在一个进程内完成这一切-您只需要确保始终避免阻塞。请特别阅读有关select()的部分。
    #include <sys/socket.h>
    #include <arpa/inet.h>
    struct NodeConnection
    {
        int fd;
        socklen_t sin_size;
        struct sockaddr_storage theirAddress; 
        char ipstr[INET6_ADDRSTRLEN];
        int port;
    };
    
    Hints set.
    Binding Socket... Socket Bound!
    server: waiting for connections...
    server: got connection from 127.0.0.1
    Socket ID: 4
    Their Address: 127.0.0.1
    Their Port: 33744
    My Size: 1
    **************
    server: got connection from 127.0.0.1
    Socket ID: 5
    Their Address: 127.0.0.1
    Their Port: 33745
    My Size: 1
    **************