1
  1. RAII 调用时不执行析构函数exit。所以WSACleanup 不运行。有什么问题?我发现 没有任何libnet使用,为什么?WSAStartupWSACleanup
  2. WSAStartup一个进程可以调用多次,那怎么保证 WSACleanup够用呢?
  3. 如何使用WSAStartupWSACleanup简单又优雅?
  4. 另外我写了这个测试代码进行测试,WSAStartup没有 WSAClean发现任何异常(内存增长或崩溃......)

代码:

int main(int argc, char *argv[])
{
    int res;

    while (1) {
        WSADATA wsadata;
        res = WSAStartup(0x0202, &wsadata);
        printf("WSAStartup 1 times:%d\n", res);

        if (res != 0) {
            printf("WSAStartup error:%d\n", WSAGetLastError());
            exit(1);
        }

        res = WSAStartup(0x0202, &wsadata);
        printf("WSAStartup 2 times:%d\n", res);

        if (res != 0) {
            printf("WSAStartup error:%d\n", WSAGetLastError());
            exit(1);
        }
    }

    return 0;
}
4

4 回答 4

1

1)exit()每个RAII 事物的问题,而不仅仅是套接字。打开文件,内存......正确的解决方案是避免exit().

2+3) 呼叫尽可能WSACleanupWSAStartup。我猜你想编写一个每个对象一个连接的套接字类,只需WSAStartup在构造函数和WSACleanup析构函数中调用。
这两种方法都在内部使用呼叫计数器,它们可以毫无问题地处理多个呼叫。

于 2015-03-13T06:01:12.657 回答
0

在我看来,exit只有当对象在堆栈上分配时才会销毁对象,无论是静态的还是全局的。不得使用 分配它new。在 的情况下new,必须显式删除对象。

好的做法是WSAStartup必须在应用程序启动和WSACleanup应用程序结束时调用。因此,您可以在其构造函数和析构函数中定义一个执行此工作的类,并定义该类的全局对象。这个类会处理这个问题。

您必须有充分的理由多次初始化 WinSock。否则,只做一次你可以轻松完成的初始化。

于 2015-03-13T06:00:48.797 回答
0

根据MS 文档-

如果应用程序需要多次获取 WSADATA 结构信息,则可以多次调用 WSAStartup。在每次这样的调用中,应用程序都可以指定 Winsock DLL 支持的任何版本号。

. . .

每次成功调用 WSAStartup 函数时,应用程序都必须调用 WSACleanup 函数。这意味着,例如,如果应用程序调用 WSAStartup 三次,它必须调用 WSACleanup 三次。对 WSACleanup 的前两次调用除了减少一个内部计数器之外什么都不做。任务的最终 WSACleanup 调用为任务执行所有必要的资源释放。

因此,可以(并且鼓励)调用WSACleanup多次调用WSAStartup,这反过来只会从WSADATA除第一次调用之外的每个调用中获取数据。

于 2020-05-25T20:18:27.247 回答
-1

RAII在调用exit时不执行析构函数。所以WSACleanup不运行。有什么问题?

输入法,没有。操作系统可以在进程终止时自行清理——这并不愚蠢。

我发现 libnet 在没有任何 WSACleanup 的情况下使用 WSAStartup,为什么?

库设计者理解上述内容 - 操作系统将清理,就像它在强制进程终止 va 期间所做的那样。任务管理器。

WSAStartup 可以在一个进程中调用多次,那么如何保证 WSACleanup 足够呢​​?

为什么要这么做?只需在启动时调用一次。任务完成。

如何轻松优雅地使用 WSAStartup 和 WSACleanup?

启动时调用 WSAStartup 一次。如果可以,请在退出时调用 WSACleanup(或者如果您喜欢它,或者如果它让您感觉更好:)。

另外我为没有 WSAClean 的测试 WSAStartup 编写了这个测试代码,没有发现任何异常(内存增长或崩溃......)

操作系统会清理,就像处理线程、文件、内存等一样。

如果通用桌面操作系统在进程终止时没有处理分配的资源,那么它显然是不可用的。

于 2015-03-13T11:36:17.890 回答