qianchenglong
qianchenglong

Reputation: 484

WSAStartup with RAII

  1. RAII does't execute destructor when call exit.So WSACleanup doesn't run.What's the problem?I found libnet use WSAStartup without any WSACleanup, why?
  2. WSAStartup can call many times in one process, so how can ensure WSACleanup enough?
  3. How to use WSAStartup and WSACleanup easily and elegantly?
  4. Additional I had wrote this test code for test WSAStartup without WSAClean, did not found any abnormal(growth of the memory or crash...)

code:

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;
}

Upvotes: 1

Views: 1109

Answers (4)

Jay
Jay

Reputation: 2868

As per the MS doc -

An application can call WSAStartup more than once if it needs to obtain the WSADATA structure information more than once. On each such call, the application can specify any version number supported by the Winsock DLL.

. . .

An application must call the WSACleanup function for every successful time the WSAStartup function is called. This means, for example, that if an application calls WSAStartup three times, it must call WSACleanup three times. The first two calls to WSACleanup do nothing except decrement an internal counter; the final WSACleanup call for the task does all necessary resource deallocation for the task.

So it's ok (and encouraged) to call WSACleanup as many times as you called WSAStartup, which, in it's turn, only gets data from WSADATA for every call but the first.

Upvotes: 0

Martin James
Martin James

Reputation: 24857

RAII does't execute destructor when call exit.So WSACleanup doesn't run.What's the problem?

IME, there is none. The OS can clean up itself upon process termination - it's not stupid.

I found libnet use WSAStartup without any WSACleanup, why?

The library designers understood the above - the OS will clean up, just like it does during forced process termination va. the Task manager.

WSAStartup can call many times in one process, so how can ensure WSACleanup enough?

Why would you do that? Just call it once at startup. Job done.

How to use WSAStartup and WSACleanup easily and elegantly?

Call WSAStartup once upon startup. Call WSACleanup upon exit if you can, (or if you feel like it, or if it makes you feel better:).

Additional I had wrote this test code for test WSAStartup without WSAClean, did not found any abnormal(growth of the memory or crash...)

The OS cleans up, just like it does with threads, files, memory etc.

If a general-purpose desktop OS did not take care of allocated resources upon process termination, it would be sensibly unuseable.

Upvotes: 0

deviantfan
deviantfan

Reputation: 11424

1) exit() is a problem for every RAII thing, not just sockets. Open files, memory... The proper solution is to avoid exit().

2+3) Call as many WSACleanup as WSAStartup. I guess you want to write a socket class with one connection per object, just call WSAStartup in the constructor and WSACleanup in the destructor.
Both methods are using a call counter inside, they handle multiple calls without problems.

Upvotes: 1

doptimusprime
doptimusprime

Reputation: 9395

In my opinion, exit will destroy the object only when the object is allocated on stack, either static or global. It must not be allocated using new. In case of new, object must be explicitly deleted.

Good practice is that WSAStartup must be called when application starts and WSACleanup when application ends. So, you can define a class which does this job in its constructor and destructor and define a global object of this class. This class will take care of this.

You must have good reason to initialize WinSock multiple times. Otherwise, do only initialization once which you can do easily.

Upvotes: 0

Related Questions