エラー コード - errno、h_errno、WSAGetLastError

Winsock アプリケーションでは、エラー コードは WSAGetLastError 関数を使用して取得されます。Windows ソケットは Windows GetLastError 関数の代わりに使用されます。 Windows ソケットによって返されるエラー コードは UNIX ソケットのエラー コード定数に似ていますが、定数はすべて WSA でプレフィックスが付いています。 したがって、Winsock アプリケーションでは WSAEWOULDBLOCK エラー コードが返されますが、UNIX アプリケーションでは EWOULDBLOCK エラー コードが返されます。

Windows ソケットによって設定されたエラー コードは、 errno 変数を介して使用できません。 また、 関数の getXbyY クラスの場合、エラー コードは h_errno 変数を介して使用できません。 WSAGetLastError 関数は、マルチスレッド プロセス内のスレッドがスレッドごとのエラー情報を取得するための信頼性の高い方法を提供することを目的としています。

バーク UNIX (BSD) との互換性を確保するために、Windows の初期バージョン (Windows 95 と Windows Socket 2 Update および Windows 98 など) では、BSD の errno.h で通常見られる通常のバークレイ エラー定数が、同等の Windows ソケット WSA エラーとして再定義されました。 たとえば、ECONNREFUSED は Winsock.h ヘッダー ファイルで WSAECONNREFUSED として定義されています。 以降のバージョンの Windows (Windows NT 3.1 以降) では、Microsoft C/C++ および Visual Studio で使用される errno.h との競合を回避するために、これらの定義がコメントアウトされました。

Microsoft Windows ソフトウェア開発キット (SDK)、プラットフォーム ソフトウェア開発キット (SDK)、Visual Studio に含まれる Winsock2.h ヘッダー ファイルには、WSA エラー定数と同じ BSD ソケット エラー コードを定義する #ifdef 0 および #endif ブロック内の 定義のコメントアウト ブロックが含まれています。 これらは、UNIX、BSD、Linux ソケット プログラミングとの互換性を提供するために使用できます。 BSD との互換性のために、アプリケーションは Winsock2.h を変更し、このブロックのコメントを解除することを選択できます。 ただし、アプリケーション開発者は、ほとんどのアプリケーションで errno.h との競合が避けられないため、このブロックのコメントを解除しないことを強くお勧めします。 また、BSD ソケット エラーは、UNIX、BSD、Linux プログラムで使用される値とは大きく異なる値に定義されます。 アプリケーション開発者は、ソケット アプリケーションで WSA エラー定数を使用することを強くお勧めします。

これらの定義は、#ifdef 0 および #endif ブロック内の Winsock2.h ヘッダーにコメントアウトされたままです。 アプリケーション開発者が互換性のために BSD エラー コードの使用を主張する場合、アプリケーションはフォームの行を含める場合があります。

#include <windows.h>

#define errno WSAGetLastError()

これにより、グローバル errno を使用するように記述されたネットワーク コードは、シングルスレッド環境で正しく機能します。 非常に深刻な欠点がいくつかあります。 ソース ファイルに、ソケット関数と非ソケット関数の両方について errno を検査するコードが含まれている場合、このメカニズムは使用できません。 さらに、アプリケーションで errno に新しい値を割り当てられません。 (Windows ソケットでは、この目的で 関数 WSASetLastError を使用できます)。

一般的な BSD スタイル

r = recv(...);
if (r == -1
    && errno == EWOULDBLOCK)
    {...}

優先スタイル

r = recv(...);
if (r == -1       /* (but see below) */
    && WSAGetLastError() == EWOULDBLOCK)
    {...}

バークレイ ソケット 4.3 と一致するエラー定数は互換性のために提供されていますが、アプリケーションでは WSA エラー コード定義を使用することを強くお勧めします。 これは、特定の Windows ソケット関数によって返されるエラー コードが、Microsoft C© で定義されている標準の範囲のエラー コードに分類されるためです。 したがって、上記のソース コード フラグメントの優れたバージョンは次のとおりです。

r = recv(...);
if (r == -1       /* (but see below) */
    && WSAGetLastError() == WSAEWOULDBLOCK)
    {...}

1995 年に定義された元の Winsock 1.1 仕様では、一連のエラー コードが推奨され、各関数の結果として返される可能性のあるエラーが一覧表示されています。 Windows Sockets 2 では、元の Winsock 仕様に記載されているものに加えて、返される他の Windows ソケット エラー コードを含む関数と機能が追加されました。 開発者が使用するために Winsock を強化するために、時間の経過と伴って追加の関数が追加されました。 たとえば、Windows XP 以降で IPv6 と IPv4 の両方をサポートする新しいネーム サービス関数 (getaddrinfogetnameinfo など) が追加されました。 以前の IPv4 専用の名前サービス関数 (関数の getXbyY クラスなど) の一部は非推奨になりました。

Windows ソケット関数によって返される可能性のあるエラー コードの完全な一覧については、「Windows ソケット エラー コード」セクションを参照してください。

Winsock エラーの処理

ソケット アプリケーションを Winsock に移植する

Windows ソケットのエラー コード

Winsock プログラミングに関する考慮事項