closesocket 函式 (winsock.h)

closesocket 函式會關閉現有的套接字。

語法

int closesocket(
  [in] SOCKET s
);

參數

[in] s

描述項,識別要關閉的套接字。

傳回值

如果沒有發生錯誤, closesocket 會傳回零。 否則,會傳回 SOCKET_ERROR 的值,並呼叫 WSAGetLastError 來擷取特定的錯誤碼。

錯誤碼 意義
WSANOTINITIALISED
使用這個函式之前,必須先進行成功的 WSAStartup 呼叫。
WSAENETDOWN
網路子系統失敗。
WSAENOTSOCK
描述項不是套接字。
WSAEINPROGRESS
封鎖的 Windows Sockets 1.1 呼叫正在進行中,或服務提供者仍在處理回呼函式。
WSAEINTR
(封鎖) Windows Socket 1.1 呼叫已透過 WSACancelBlockingCall 取消。
WSAEWOULDBLOCK
套接字標示為非封鎖,但 linger 結構的l_onoff成員會設定為非零值,而 linger 結構的l_linger成員會設定為非零逾時值。

備註

closesocket 函式會關閉套接字。 使用它來釋放在 s 參數中傳遞的套接字描述元。 請注意,在發出 closesocket 函式時,系統可能會立即重複使用傳入 s 參數的套接字描述符。 因此,預期傳入 s 參數之套接字描述元的進一步參考無法失敗,並出現錯誤 WSAENOTSOCK。 Winsock 用戶端絕對不能在與另一個 Winsock 函數調用同時發出closesocket

( WSASend/ WSASendTo/ WSARecv WSARecvWSARecvFrom/ 的任何擱置重疊傳送和接收作業,也會取消此進程中任何線程所發出的重疊套接字) 。 會執行針對這些重疊作業指定的任何事件、完成例程或完成埠動作。 擱置的重迭作業失敗,錯誤狀態 WSA_OPERATION_ABORTED

應用程式不應該假設套接字上任何未完成的 I/O 作業都會保證會在 closesocket 傳回時完成。 closesocket 函式會在未處理的 I/O 作業上起始取消,但這並不表示應用程式會在關閉ocket 函式傳回時收到這些 I/O 作業的 I/O 完成。 因此,應用程式不應該清除 WSAOVERLAPPED 結構 (任何資源,例如) 未處理 I/O 要求所參考,直到 I/O 要求確實完成為止。

應用程式應該一律有一個相符的呼叫,可讓每個成功呼叫套接字的 closesocket,將任何套接字資源傳回系統。

linger 結構會維護特定套接字的相關信息,指定當數據排入佇列傳送時該套接字的行為,並在套接字上呼叫 closesocket 函式。

linger 結構的l_onoff成員會決定套接字是否應該在 closesocket 函式呼叫之後保留開啟指定的時間,以便傳送佇列數據。 此成員可以透過兩種方式修改:

  • 呼叫 setsockopt 函式,並將 optname 參數設定為 SO_DONTLINGERoptval 參數會決定l_onoff成員的修改方式。
  • 呼叫 setsockopt 函式,並將 optname 參數設定為 SO_LINGERoptval 參數會指定如何修改l_onoffl_linger成員。

linger 結構的l_linger成員決定套接字應該保持開啟的時間量,以秒為單位。 只有當 linger 結構的l_onoff成員為非零時,才適用這個成員。

套接字的預設參數是 linger 結構的l_onoff成員為零,表示套接字不應保持開啟狀態。 linger 結構l_linger成員的預設值為零,但當l_onoff成員設定為零時,會忽略此值。

若要讓套接字保持開啟狀態,應用程式應將 l_onoff 成員設定為非零值,並將 l_linger 成員設定為所需的逾時,以秒為單位。 若要停用剩餘開啟的套接字,應用程式只需要將延遲結構l_onoff成員設定為零。

如果應用程式呼叫 setockopt 函式,並將 optname 參數設定為 SO_DONTLINGER 以將 l_onoff 成員設定為非零值,則不會指定 l_linger 成員的值。 在此情況下,使用的逾時取決於實作。 如果先前呼叫 setockopt 函式且 optname 參數設定為 SO_LINGER) 的 setockopt 函式,已為套接字 (建立先前逾時,服務提供者應恢復此逾時值。

closesocket 函式的語意會受到設定 linger 結構成員的套接字選項所影響。

l_onoff l_linger 關閉的類型 等候關閉嗎?
不小心 正常關閉 No
實心 No
如果所有數據在 l_linger 成員中指定的逾時值內傳送,則為正常。

如果所有數據無法在 l_linger 成員中指定的逾時值內傳送,則為困難。

Yes
 

如果 LINGER 結構的l_onoff成員在數據流套接字上為零,closesocket 呼叫會立即傳回,而且不會接收 WSAEWOULDBLOCK,不論套接字是封鎖還是非封鎖。 不過,在基礎套接字關閉之前,會盡可能傳送任何排入佇列進行傳輸的數據。 這也稱為正常中斷連線或關閉。 在此情況下,Windows Sockets 提供者無法釋放套接字和其他資源一段任意期間,因而影響預期使用所有可用套接字的應用程式。 這是套接字的預設行為。

如果 linger 結構的l_onoff成員為非零,且l_linger成員為零,即使尚未傳送或認可佇列數據,也不會封鎖 closesocket。 這稱為硬式或中止關閉,因為套接字的虛擬線路會立即重設,而且任何未傳送的數據都會遺失。 在 Windows 上,線路遠端端的任何 recv 呼叫都會因為 WSAECONNRESET 而失敗。

如果 linger 結構的l_onoff成員設定為非零,且l_linger成員在封鎖套接字上設定為非零逾時,則 closesocket 呼叫會封鎖,直到傳送剩餘的數據或逾時到期為止。 如果在 l_linger 成員中指定的逾時值內傳送所有數據,這稱為正常中斷連線或關閉。 如果逾時在傳送所有數據之前到期,Windows Sockets 實作會在 closesocket 傳回之前終止連線,這稱為硬式或中止關閉。

不建議在非封鎖套接字上將 linger 結構的l_onoff成員設定為非零,而且不建議使用非零逾時間隔的l_linger成員。 在此情況下,如果關閉作業無法立即完成, 對 closesocket 的呼叫將會失敗,並出現 WSAEWOULDBLOCK 錯誤。 如果 closesocketWSAEWOULDBLOCK 而失敗,套接字句柄仍然有效,而且不會起始中斷連線。 應用程式必須再次呼叫 closesocket ,才能關閉套接字。

如果 linger 結構的l_onoff成員為非零,且l_linger成員是封鎖套接字的非零逾時間隔,則 closesocket 函式的結果無法用來判斷所有數據是否已傳送至對等。 如果在 l_linger 成員中指定的逾時之前傳送數據,或連接已中止, closesocket 函式將不會傳回錯誤碼, (closesocket 函式的傳回值是零) 。

closesocket 呼叫只會封鎖,直到所有數據傳遞至對等或逾時到期為止。 如果連線因為逾時過期而重設,套接字就不會進入TIME_WAIT狀態。 如果在逾時期間內傳送所有數據,套接字就可以進入TIME_WAIT狀態。

如果延遲結構l_onoff成員為非零,且l_linger成員為封鎖套接字的零逾時間隔,則 closesocket 的呼叫將會重設連線。 套接字不會進入TIME_WAIT狀態。

您可以使用 optname 參數設定為 SO_LINGER 來呼叫 getsockopt 函式,以擷取與套接字相關聯之 linger 結構的目前值。

注意為了確保在連線上傳送和接收所有數據,應用程式應該在呼叫 closesocket 之前先呼叫關機, (請參閱正常關機、linger 選項和套接字關閉,以取得詳細資訊) 。 另請注意,呼叫 closesocket 之後,不會張貼FD_CLOSE網路事件。
 

以下是 closesocket 行為的摘要:

  • 如果 LINGER 結構的l_onoff成員為零, (套接字) 的預設值,closesocket 會立即傳回,且連接會在背景正常關閉。
  • 如果 linger 結構的l_onoff成員設定為非零,且l_linger成員設定為零, (沒有逾時) closesocket 會立即傳回,且連接已重設或終止。
  • 如果 linger 結構的l_onoff成員設定為非零,且l_linger成員設定為非零逾時:– 針對封鎖套接字,請關閉ocket 區塊,直到傳送所有數據或逾時到期為止。

    – 針對非封鎖套接字, closesocket 會立即傳回指出失敗。

如需詳細資訊,請參閱 正常關機、Linger 選項和套接字關閉 ,以取得詳細資訊。

注意 發出封鎖的 Winsock 呼叫,例如 closesocket 時,Winsock 可能需要等候網路事件,才能完成呼叫。 Winsock 會在這種情況中執行可警示的等候,而異步過程調用 (APC) 排程在同一個線程上,可能會中斷。 在 APC 內發出另一個封鎖 Winsock 呼叫,中斷相同線程上持續封鎖 Winsock 呼叫會導致未定義的行為,而且永遠不會由 Winsock 客戶端嘗試。
 

IrDA 套接字注意事項

請記住下列要點:

  • 必須明確包含 Af_irda.h 頭檔。
  • 支援標準後置選項。
  • 雖然 IrDA 未提供正常關閉,但 IrDA 會延遲關閉,直到清除接收佇列為止。 因此,應用程式可以傳送數據並立即呼叫 套接字 函式,並確信接收者會在接收FD_CLOSE訊息之前先複製數據。

ATM 的注意事項

以下是使用異步傳輸模式 (ATM) 和 Windows Sockets 2 時,與聯機終止相關聯的重要問題:

  • 使用 closesocketshutdown 函式搭配SD_SEND或SD_BOTH會導致在控制通道上傳送 RELEASE 訊號。 由於 ATM 使用個別的訊號和數據通道,發行訊號可能會在最後一個數據到達目的地之前到達遠端端,而導致該數據遺失。 其中一個可能的解決方案是在傳送的最後一個數據與 ATM 套接字的 closesocket 或 shutdown 函 呼叫之間,設計足夠的延遲。
  • ATM 不支援半關閉。
  • 中止和正常中斷聯機會導致發行訊號與相同原因欄位一起傳送。 不論是哪一種情況,在套接字的遠端接收的數據仍會傳遞至應用程式。 如需詳細資訊 ,請參閱正常關機、擷取選項和套接字關閉

Windows Phone 8:Windows Phone 8 和更新版本上的 Windows Phone Store 應用程式支援此函式。

Windows 8.1Windows Server 2012 R2:Windows 市集應用程式支援此函式,Windows 8.1、Windows Server 2012 R2 和更新版本。

規格需求

需求
最低支援的用戶端 Windows 8.1、Windows Vista [傳統型應用程式 |UWP 應用程式]
最低支援的伺服器 Windows Server 2003 [傳統型應用程式 |UWP 應用程式]
目標平台 Windows
標頭 winsock.h (包含 Winsock2.h)
程式庫 Ws2_32.lib
Dll Ws2_32.dll

另請參閱

正常關機、擷取選項和套接字關閉

WSAAsyncSelect

WSADuplicateSocket

WSAOVERLAPPED

Winsock 函式

Winsock 參考

接受

getsockopt

ioctlsocket

縈繞

setsockopt

socket