[英]WSAStartup with RAII
exit
時不執行析構函數。所以WSACleanup
不運行。有什么問題?我發現libnet
使用WSAStartup
沒有任何WSACleanup
,為什么?WSAStartup
可以在一個進程中調用多次,那么如何保證WSACleanup
足夠呢?WSAStartup
和WSACleanup
?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;
}
1) exit()
是每個RAII 事物的問題,而不僅僅是套接字。 打開文件,內存......正確的解決方案是避免exit()
。
2+3) 調用與WSAStartup
一樣多的WSACleanup
。 我猜您想編寫一個每個對象一個連接的套接字類,只需在構造函數中調用WSAStartup
,在析構函數中調用WSACleanup
。
兩種方法都在內部使用調用計數器,它們可以毫無問題地處理多個調用。
在我看來, exit
只會在對象在堆棧上分配時銷毀對象,無論是靜態的還是全局的。 不得使用new
分配。 在new
情況下,必須明確刪除 object。
好的做法是在應用程序啟動時必須調用WSAStartup
,在應用程序結束時必須調用WSACleanup
。 因此,您可以定義一個在其構造函數和析構函數中執行此工作的類,並定義此類的全局對象。 這個類會處理這個。
您必須有充分的理由多次初始化 WinSock。 否則,只需進行一次初始化即可輕松完成。
根據MS 文檔-
如果應用程序需要多次獲取 WSADATA 結構信息,它可以多次調用 WSAStartup。 在每次這樣的調用中,應用程序可以指定 Winsock DLL 支持的任何版本號。
. . .
應用程序必須在每次成功調用 WSAStartup 函數時調用 WSACleanup 函數。 這意味着,例如,如果應用程序調用 WSAStartup 3 次,則它必須調用 WSACleanup 3 次。 對 WSACleanup 的前兩次調用除了減少內部計數器外什么都不做; 任務的最終 WSACleanup 調用為任務執行所有必要的資源釋放。
因此,可以(並鼓勵)調用WSACleanup
次數與調用WSAStartup
次數一樣多,反過來,它只從WSADATA
獲取數據, WSADATA
一次調用WSADATA
,每次調用都從WSADATA
獲取數據。
RAII 在調用 exit 時不執行析構函數。所以 WSACleanup 不運行。有什么問題?
IME,沒有。 操作系統可以在進程終止時自行清理 - 這並不愚蠢。
我發現 libnet 使用 WSAStartup 而沒有任何 WSACleanup,為什么?
庫設計者理解上述內容 - 操作系統將進行清理,就像它在強制進程終止 va 期間所做的那樣。 任務管理器。
WSAStartup 可以在一個進程中調用多次,那么如何保證 WSACleanup 足夠呢?
為什么要這么做? 只需在啟動時調用一次。 任務完成。
如何輕松優雅地使用 WSAStartup 和 WSACleanup?
啟動時調用一次 WSAStartup。 如果可以,請在退出時調用 WSACleanup(或者如果您願意,或者如果它讓您感覺更好:)。
另外我寫了這個測試代碼來測試沒有WSAClean的WSAStartup,沒有發現任何異常(內存增長或崩潰......)
操作系統會進行清理,就像處理線程、文件、內存等一樣。
如果通用桌面操作系統在進程終止時不處理分配的資源,那么它顯然無法使用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.