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
如何使用RAII为套接字建模 我是C++的新手,我从概念上理解RAII应该如何工作,但是我很难把一个简单的socket连接处理程序安装到它里面。_C++_Sockets_Raii - Fatal编程技术网

如何使用RAII为套接字建模 我是C++的新手,我从概念上理解RAII应该如何工作,但是我很难把一个简单的socket连接处理程序安装到它里面。

如何使用RAII为套接字建模 我是C++的新手,我从概念上理解RAII应该如何工作,但是我很难把一个简单的socket连接处理程序安装到它里面。,c++,sockets,raii,C++,Sockets,Raii,当前代码: void accept_ev(event_handler::token &t, int listenfd) { int newfd = accept(listenfd, NULL, NULL); if (newfd < 0) throw api_server_accept_failed(*this, errno); connections.insert(api_server_connection(newfd)); } 这显然

当前代码:

void accept_ev(event_handler::token &t, int listenfd)
{
    int newfd = accept(listenfd, NULL, NULL);

    if (newfd < 0)
        throw api_server_accept_failed(*this, errno);

    connections.insert(api_server_connection(newfd));
}
这显然是不安全的,因为api_服务器_连接构造函数可能会在将fd分配给其成员变量之前引发异常

所以我的下一个想法是将accept移到构造函数中。问题是我真的希望api_服务器_连接不知道fd来自何处。例如,如果我想在将来支持inetd,它也可以作为fd0传递到程序中

那么我该怎么做呢。我应该为每种方式使用不同的构造函数来获得fd吗?我是否应该创建子类?另一种选择是使用lambda函数


或者,在这种情况下,我应该捕获任何错误并关闭调用程序中的fd吗?

首先,为了使用RAII,您必须以面向对象的方式进行思考。因此,我看到您试图使用C++实现服务器类。在这种情况下,您将仅在服务器初始化时使用RAII,这意味着您将编写代码并在服务器开始侦听端口时完成它。构造函数中的最后一个函数调用必须是侦听或启动线程连接。之后,您必须实现第二个线程,该线程将处理客户端连接。第二个线程将调用accept以接受客户机,并在服务器工作时处于迭代中。在析构函数中,您只需将侦听标志设置为false,然后等待accept线程终止,然后关闭所有套接字。

首先,为了使用RAII,您必须以面向对象的方式进行思考。因此,我看到您试图使用C++实现服务器类。在这种情况下,您将仅在服务器初始化时使用RAII,这意味着您将编写代码并在服务器开始侦听端口时完成它。构造函数中的最后一个函数调用必须是侦听或启动线程连接。之后,您必须实现第二个线程,该线程将处理客户端连接。第二个线程将调用accept以接受客户机,并在服务器工作时处于迭代中。在析构函数中,您只需将侦听标志设置为false,然后等待accept线程终止,然后关闭所有套接字。

忽略套接字目前,您通常要做的是将事情分为两个阶段

在第一阶段中,您可以执行一些可能会抛出的操作,但如果执行了这些操作,您可以将系统恢复到正常状态,最好是一种完全没有发生任何事情的状态

在第二阶段,你做了一些你可能无法撤销的事情,但你肯定永远不会放弃

要做到这一点,您需要一些关于可以/将抛出什么的保证,特别是一些关于至少几个完全不能抛出的相当具体的操作的保证,例如,交换两个项目

为了促进这一点,您通常希望在dtor中恢复到正常状态,因此如果抛出异常,析构函数将自动清除


不幸的是,关于您的特定代码/情况,很难说得更多,因为我们对您正在使用的类了解不够

忽略,目前,您通常要做的是将事情分为两个阶段

在第一阶段中,您可以执行一些可能会抛出的操作,但如果执行了这些操作,您可以将系统恢复到正常状态,最好是一种完全没有发生任何事情的状态

在第二阶段,你做了一些你可能无法撤销的事情,但你肯定永远不会放弃

要做到这一点,您需要一些关于可以/将抛出什么的保证,特别是一些关于至少几个完全不能抛出的相当具体的操作的保证,例如,交换两个项目

为了促进这一点,您通常希望在dtor中恢复到正常状态,因此如果抛出异常,析构函数将自动清除


不幸的是,关于您的特定代码/情况,很难说得更多,因为我们对您正在使用的类了解不够

你看过/读过如何工作吗?您是否考虑过完全跳过这一步,只使用ASIO?api\u服务器\u连接如何引发异常?你还没有给我们看代码。@R.MartinhoFernandes我还没有写出来。。。但我知道它会有pimpl,这意味着内存分配,这可能会失败。@JerryCoffin我没有,但这个问题并不是关于套接字的,我犹豫了一下是否要添加那个标记,而是RAII。你看过/读过它的工作原理吗?您是否考虑过完全跳过这一步,只使用ASIO?api\u服务器\u连接如何引发异常?你还没有给我们看代码。@R.MartinhoFernandes我还没写呢
... 但我知道它会有pimpl,这意味着内存分配,这可能会失败。@JerryCoffin我没有,但这个问题并不是关于套接字,我犹豫了一下是否添加那个标记,而是RAII。我想你实际上让我用正确的方式思考,所以我想我应该接受这个问题。我将创建一个fd_guard类,并首先将fd插入其中,以一种不会失败的方式。然后我可以毫无顾虑地创建连接对象,并让它继承fd或fd_保护。我想你实际上让我以正确的方式思考,所以我想我应该接受这一点。我将创建一个fd_guard类,并首先将fd插入其中,以一种不会失败的方式。然后,我可以创建连接对象而不用担心,并让它继承fd或fd_保护。