1
  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;
}
MD XF
  • 7,860
  • 7
  • 40
  • 71
qianchenglong
  • 474
  • 5
  • 13

4 Answers4

1

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.

deviantfan
  • 11,268
  • 3
  • 32
  • 49
  • Not, I just test and use some library like `libnet` which call `WSAStartup` withourt `WSACleanup` and I also call `WSAStartup`! – qianchenglong Mar 13 '15 at 06:51
  • @qianchenglong I don´t think I understand what you want to say. If a library without any maintenance or other activity for 12 years has bad code, don´t use it. – deviantfan Mar 13 '15 at 06:55
  • Acttually I don't care it much.I want to known `WSAStartup` without `WSACleanup` will cause any problem and RAII with `exit` how to solve. – qianchenglong Mar 13 '15 at 06:58
  • `I want to known WSAStartup without WSACleanup will cause any problem` Maybe. The answer is within the source code of Windows and can change with every update. The docs require that you call WSACleanup too, so you have to do it. `RAII with exit how to solve` As I wrote above, don´t use exit. Use a better program design. – deviantfan Mar 13 '15 at 07:02
  • So when `socket error` happens, how to exit program without interrupts RAII? – qianchenglong Mar 13 '15 at 07:17
  • If the socket class gets an error by a raw socket function, pass it up to the thing that uses the socket class (exceptions or return value...). This thing can decide how to proceed (retry later, tell the user, delegate it again to the parent...). Once some error is so problematic that it gets up to main(), you can terminate the program there with a simple and safe `return`. – deviantfan Mar 13 '15 at 07:35
  • If failing to call WSACleanup was such a huge problem, then you would be forbidden to use the Task Manager to close processes. Empirically, it's no problem at all on any Windows OS I've ever used. – Martin James Mar 13 '15 at 11:27
  • @MartinJames So just because the OS can mitigate most things, you tell him to never clean up anything (and to terminate the program because of every minor recoverable error)? – deviantfan Mar 13 '15 at 12:48
  • @deviantfan IF there is a resource that the OS can clean up AND there is no overriding reason to write user code to do the same job, there is no upside to writing the user code and several downsides, eg. you have to actually write extra, redundant code that will, of course, have bugs, require testing and require maintaining. – Martin James Mar 19 '15 at 21:01
0

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.

doptimusprime
  • 9,115
  • 6
  • 52
  • 90
  • `exit` will run destructor in global or static varialbe.Sometimes I need to ues any library like `libnet`.I found in `libnet` which call `WSAStartup` without `WSACleanup`. Also In my class sometime need `exit`, so the RAII does't work. – qianchenglong Mar 13 '15 at 06:04
  • That is what I say. It will not destroy objects allocated using pointers. – doptimusprime Mar 13 '15 at 06:34
  • @qianchenglong `Also In my class sometime need exit` Then redesign your program. – deviantfan Mar 13 '15 at 06:49
  • 'Note that objects with automatic storage are not destroyed by calling exit (C++).'. Also,, termination of a process va an exit() call is not a problem unless your app requirements force it to be, and even then you should design your system so that unintentional 'terminations', (eg. power fail), do not cause data integrity or other such problems on restart. – Martin James Mar 13 '15 at 11:24
0

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.

Martin James
  • 24,453
  • 3
  • 36
  • 60
0

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.

Jay
  • 2,535
  • 3
  • 32
  • 44