closesocket

closesocket関数は既存のソケットをクローズします。

SOCKET closesocket(
    SOCKET s             // socket discriptor
);

WS2_32.DLL

引数

s

クローズしようとしているソケットを識別するディスクリプタを指定します。

戻り値

成功すると0を返します。

失敗すると-1 (SOCKET_ERROR) を返します。特定のエラーコードを取得するにはWSAGetLastError関数を呼び出します。

10004 (WSAEINTR)

(ブロッキング)Windows Sockets 1.1呼び出しがWSACancelBlockingCallによりキャンセルされました。

10035 (WSAEWOULDBLOCK)

ソケットが非ブロッキングとしてマークされていますが、linger構造体のl_onoffメンバにゼロ以外の値が設定され、かつlinger構造体のl_lingerメンバがゼロ以外のタイムアウト値が設定されています。

10036 (WSAEINPROGRESS)

ブロッキングWindows Sockets 1.1呼び出しが実行中であるか、サービスプロバイダがコールバック関数を実行中です。

10038 (WSAENOTSOCK)

指定されたディスクリプタはソケットではありません。

10050 (WSAENETDOWN)

ネットワークサブシステムが失敗しました。

10093 (WSANOTINITIALISED)

この関数を呼び出す前にWSAStartup関数の呼び出しが成功していなければなりません。

解説

closesocket関数はソケットをクローズします。ソケットディスクリプタsを解放するにはこの関数を使用してください。以降のsへの参照はエラーWSAENOTSOCKで失敗します。これが基本ソケットへの最後の参照である場合は、関連付けられた名前付け情報とキューイングされたデータが破棄されます。ポストされた通知メッセージを除き、現在のプロセスのすべてのスレッドにより発行されたすべての保留中のブロッキング、非同期呼び出しがキャンセルされます。

現在のプロセスのすべてのスレッドにより発行されたあらゆるオーバーラップ送受信操作(オーバーラップソケットに対するWSASend, WSASendTo, WSARecv, WSARecvFrom)についても同様にキャンセルされます。これらのオーバーラップ操作に対するイベント、完了ルーチン、完了ポート処理はすべて実行されます。保留中のオーバーラップ操作はWSA_OPERATION_ABORTEDエラーコードで失敗します

アプリケーションは、closesocket関数が制御を返した時点でソケットに関するすべての未解決のI/O操作が完了していることが保証されていると仮定すべきではありません。closesocket関数は未解決のI/O操作のキャンセル処理を開始しますが、これは、closesocket関数から制御が返るまでにアプリケーションがこれらのI/O操作に対するI/O完了を受け取るということではありません。したがって、アプリケーションは、I/O要求が実際に完了するまで、未解決のI/O要求により参照されるあらゆるリソース(例えばWSAOVERLAPPED構造体)をクリーンアップすべきではありません。

アプリケーションは常に、各々のsocket関数の呼び出し成功に対してclosesocketの呼び出しを一致させ、すべてのソケットリソースをシステムに返すようにするべきです。

linger構造体のl_onoffメンバは、closesocket関数が呼び出されてから指定された時間の間だけソケットがオープンされた状態を維持することにより、キューイングされているデータが送信されるようにすべきかどうかを決定します。このメンバは以下の2通りの方法で変更することができます。

linger構造体のl_lingerメンバは、ソケットがオープンされた状態を維持する時間を秒単位で決定します。このメンバは、linger構造体のl_onoffメンバがゼロ以外の値の場合にのみ適用されます。

ソケットのデフォルトのパラメータは、linger構造体のl_onoffメンバはゼロで、ソケットがオープンされた状態を維持しないことを表します。linger構造体のl_lingerメンバに対するデフォルトの値はゼロですが、この値はl_onoffメンバがゼロに設定されているときは無視されます。

ソケットがオープンされた状態が維持されるようにするには、アプリケーションはl_onoffメンバの値をゼロ以外の値にして、l_lingerメンバを秒単位の要求タイムアウトに設定するべきです。ソケットがオープンされたままにならないようにするには、アプリケーションはlinger構造体のl_onoffメンバをゼロに設定することだけが必要です。

アプリケーションがoptnameパラメータにSO_DONTLINGERを指定してsetsockopt関数を呼び出すことによってl_onoffメンバをゼロ以外の値に設定する場合、l_lingerメンバに対する値は指定されません。この場合には使用されるタイムアウトは実装依存です。(前回のsetsockopt関数呼び出しでoptnameパラメータにSO_LINGERを設定することによって)前回のタイムアウトがソケットに対して設定されていた場合、サービスプロバイダは再度そのタイムアウト値を設定するべきです。

closesocket関数のセマンティックスはlinger構造体のメンバに設定されるソケットオプションに影響されます。

l_onoff l_linger クローズ形式 クローズ待機
0 任意 graceful close なし
0以外 0 hard なし
0以外 0以外

l_lingerメンバで指定されたタイムアウト値以内に全データが送信された場合はgraceful

l_lingerメンバで指定されたタイムアウト値以内に全データを送信できなかった場合はhard

あり

ストリームソケットにおいてlinger構造体のl_onoffメンバがゼロの場合は、ソケットがブロッキングであるか非ブロッキングであるかに関わらずclosesocket呼び出しは直ちに制御を返し、WSAEWOULDBLOCKエラーは受け取りません。ただし、送信のためにキューイングされているすべてのデータは、可能であれば、基本ソケットがクローズされる前に送信されます。これはgraceful(上品な)切断またはgracefulクローズとも呼ばれます。この場合、Windows Socketsプロバイダは任意の時間ソケットとその他のリソースを解放することができません。したがって、すべての利用可能なソケットを使用することを期待するアプリケーションに影響します。これはソケットの既定の振る舞いです。

linger構造体のl_onoffメンバがゼロ以外で、かつl_lingerメンバがゼロである場合、たとえキューイングされているデータがまだ送信または受信確認されていない場合であっても、closesocketはブロックされません。この方法ではソケットの仮想通信路が直ちにリセットされ、すべての未送信データが喪失するため、hard(硬い)クローズまたはabortive(失敗の)クローズと呼ばれます。Windows上では、通信路のリモート側でのrecv呼び出しはWSAECONNRESETエラーで失敗します。

linger構造体のl_onoffメンバがゼロ以外で、かつl_lingerメンバがゼロ以外のブロッキングソケットに対するタイムアウトが設定されている場合、closesocket呼び出しは、残っているデータが送信されるか、タイムアウトが経過するまでブロックします。l_lingerメンバで指定されたタイムアウト値以内にすべてのデータが送信された場合、これはgraceful切断またはgracefulクローズと呼ばれます。すべてのデータが送信されるより前にタイムアウトが経過した場合は、Windows Sockets実装はclosesocketが制御を返す前にコネクションを終了させます。これはhardクローズまたはabortiveクローズと呼ばれます。

非ブロッキングソケットにおいてlinger構造体のl_onoffメンバにゼロ以外の値を設定し、l_lingerメンバにゼロ以外のタイムアウト値を設定することは推奨されません。この場合、クローズ操作を直ちに完了できなかった場合にclosesocketの呼び出しはWSAWOULDBLOCKエラーで失敗します。closesocketWSAWOULDBLOCKエラーで失敗した場合、ソケットハンドルは依然として有効で、切断処理は開始されていません。そのため、アプリケーションは再度closesocketを呼び出してソケットをクローズしなければなりません。

ブロッキングソケットにおいてlinger構造体のl_onoffメンバがゼロ以外で、かつl_lingerメンバがゼロ以外のタイムアウト間隔が設定されている場合、closesocket関数の結果から、すべてのデータが接続先へ送信されたかどうかを決定することはできません。l_lingerメンバで指定されたタイムアウトが経過するより前にデータが送信された場合でも、または、コネクションが中止された場合であっても、closesocket関数はエラーコードを返しません(closesocket関数の戻り値はゼロになります)。closesocket呼び出しは、すべてのデータが接続先に送信されるか、タイムアウトが経過するまで、単にブロックするのみです。タイムアウトが経過したためにコネクションがリセットされた場合には、ソケットはTIME_WAIT状態になりません。タイムアウト期間以内にすべてのデータが送信された場合はソケットはTIME_WAIT状態になる可能性があります。

ブロッキングソケットにおいてlinger構造体のl_onoffメンバがゼロ以外で、かつl_lingerメンバがゼロのタイムアウト間隔である場合は、closesocketの呼び出しはコネクションをリセットします。ソケットはTIME_WAIT状態になりません。

optnameパラメータにSO_LINGERを設定してgetsockopt関数を呼び出すことで、ソケットに関連するlinger構造体の現在の値を取得することができます。

Note: コネクション上ですべてのデータが送信および受信されることを保証するには、アプリケーションはclosesocketを呼び出す前にshutdownを呼び出すべきです。closesocketが呼び出された後はFD_CLOSEネットワークイベントがポストされないことにも注意してください。

以下にclosesocketの振る舞いをまとめます。

IrDAソケットに関する注意

以下のことに注意を払う必要があります。

ATMに関する注意

Windows Sockets 2で非同期転送モード(ATM)を使用する際に留意しておかなければならない、接続終了に関する重要な事項を以下に記載します。

対応情報

Windows 95 以降 / Windows NT 3.51 以降