Winsock

Winsock (Windows Sockets API, WSA) は、Windowsにおいてネットワークソフトウェアがネットワークサービス（特にTCP/IP）にアクセスする方法を定義した技術仕様である。Windows 上のTCP/IPクライアントアプリケーション（FTPクライアントや Gopherクライアント）とTCP/IPプロトコルスタックとの標準インタフェースを定義している。その名称はBSD系UNIXでプログラム間の通信に使われたソケットと呼ばれるAPIモデルに基づいている。winsock.dll というDLLファイルはWSAインタフェースの主要部分を提供するものであったため、このAPIを Winsock という略称で呼ぶことには開発者側の抵抗があったし、ユーザー側にも多くの混乱があった。ユーザーは winsock.dll さえあれば、TCP/IP プロトコルが完全にサポートされるのだと誤解していることが多かった。 初期のマイクロソフトのオペレーティングシステム（MS-DOSもWindowsも）は、ネットワーク機能が貧弱で、NetBIOS/NetBEUIを主に使っていた。これは階層化されていない、ルーティング不可能なネットワーク機能であり、IBM の NetBIOS をマイクロソフトが実装したものであった。特に当時、マイクロソフトはTCP/IPを完全に無視していた。数々の大学グループ（MIT）や商用ベンダー（サン・マイクロシステムズ他）がMS-DOS用TCP/IPを開発し、ハードウェアに同梱するなどして販売していた。Windows がリリースされると、さらに Windows 向け TCP/IP を提供するベンダーが増えていった。しかし、マイクロソフトは相変わらず機能の貧弱な製品を提供していた。 これらベンダーの製品の弱点は、それぞれ独自のAPIを採用していた点である。また、メモリ使用量（当時、640KBもあれば大容量とされていた）や、複数のプロトコルを並行してサポートする方法がない点も問題だった。特に最後の問題点は重要であった。当時のネットワーク環境はベンダー毎に異なり（例えば、DECのDECnet、ノベルのNetware、Banyan Vines、IBM Lan Manager など）、それぞれ違ったプロトコルを使っていた（例えば、ノベルは IPX/SPX、IBM は NetBIOS API ベースのプロトコル、マイクロソフトは NetBEUI Frames Protocol）。従って、ユーザーが複数のネットワークサービスに接続するには、複数のブート構成を用意し、使いたいサービスに合わせて立ち上げ直して、対応するプロトコルを使えるようにする必要があった。さらにプログラミングモデルが統一されていないため、任意のベンダーのTCP/IP実装で動作するネットワークアプリケーションの開発は非常に困難であった。何らかの「標準化」が必要であることは明らかであった。 当時既にPCネットワークの分野での標準化はいくつも進められていた。アメリカ空軍の支援で行われた標準化として RFC 1001 と RFC 1002 がある。これは TCP/IP 上の NetBIOS 実装であり、NBT (NetBIOS over TCP/IP) と呼ばれた。次に FTP Software 社が中心となって進められた Crynwr packet driver がある。これは、上述したメモリ使用量の問題をアセンブリ言語で実装することで回避し、ネットワークカードの割り込みを独占しないことで複数プロトコルの同時サポート問題にも対応した。同様の試みとしてノベルのODI (Open Data-Link Interface) やマイクロソフトのNDIS (Network Driver Interface Specification) といったAPIがある。これらはTCP/IPも含めたプロトコルスタックの完全な実装ではない点が重要である。従って、例えば Crynwr の Russ Nelson が開発した QVT や WinQVT はDECのVT220端末エミュレータだが、どちらもアプリケーション内にTCP/IPスタックを持っていた。packet driver と同時に使うことが可能で、例えばノベルのIPX/SPXでNetWareのファイルサーバにアクセスすると同時に、DECのVMSにTCP/IP経由でアクセスすることが可能であった。明らかにこのような環境がこのプロジェクトの目指したものであり、例えばパリのOECDなどでそのような使われ方をしていた。 Windows Sockets API を提案したのは JSB Software の Martin Hall であり、1991年10月、CompuServeでの電子掲示板での議論が最初であった。仕様の第1版を編集したのは Martin Hall、Mark Towfiq（Microdyne、後にサン・マイクロシステムズ）、Geoff Arnold（サン・マイクロシステムズ）、Henry Sanders と J Allard（マイクロソフト）らである。著作権や知的所有権について議論があり、IETF を通すとか非営利団体を結成するといった議論がなされた。結局、単純に著作権は5人がそれぞれ所有することとなった。後に J Allard はマイクロソフト社内に大きなオフィスを与えられ、そこで ACK と NACK と名づけたイグアナを飼った。 Windows Socket API 仕様は2つのインタフェースを定義している。1つはアプリケーションソフトウェア開発者が利用するAPIであり、もう1つはネットワークソフトウェア開発者が新たなプロトコルモジュールをシステムに追加する際に利用するSPIである。APIは準拠アプリケーションがWinsockに準拠して実装された任意のプロトコルを使って動作可能であることを保証する。SPI は準拠プロトコルモジュールを Windows に追加可能であることと、任意のAPI準拠アプリケーションから利用可能となることを保証する。リリース当初、複数プロトコルサポートが必須だったため、このような保証は重要だったが、今では学問的興味から語られるだけである。Windows Socket version 2.0には IPX/SPX で使われる機能も含まれているが、Winsock 2.0 リリース当時から既に廃れつつあるプロトコルであり、今ではこれを使うものはほとんどないだろう。マイクロソフトは最近の Windows には必ず高品質なTCP/IPスタックを実装しており、その代替となる有力な製品も存在しない。さらに言えば、TCP/IP 以外のプロトコルを実装しなければならない強い動機も存在しない。 Windows Sockets はバークレーのソケットに基づいているが、Windows の標準プログラミングモデルに対応するために機能を追加している。Winsock はソケットのほとんどの機能をカバーしているが、Windows と UNIX の根本的な違いからどうしても避けられない差異も生じている（とは言っても、STREAMSとの差異に比べれば、ずっとソケットに近い）。APIに含まれる全ての関数名の頭にはWSAが付く。例えばホスト名参照の WSAGetHostByName() などである。BSDソケットからの拡張で特筆すべきは、「非同期ソケット」およびオーバーラップI/Oを利用した「オーバーラップソケット」である。非同期バージョンの関数は、接頭辞として WSAAsync を付け、WSAAsyncGetHostByName() などという名前になっており、Windowsのウィンドウメッセージによって結果を通知する。非同期処理のキャンセルはWSACancelAsyncRequest()で実行する。オーバーラップソケットは完了通知にWSAEVENTオブジェクトとWSAOVERLAPPED構造体を使用する。なお、Winsockの非同期ソケットやオーバーラップソケットは、BSDのノンブロッキングソケットとは異なる概念である。ブロッキングモードのsend()およびrecv()のタイムアウト時間を設定するソケットオプションSO_SNDTIMEOおよびSO_RCVTIMEOを使用するには、ソケット作成時にWSA_FLAG_OVERLAPPED属性が設定されている必要がある。Winsock2では、ソケットは既定でブロッキングモードで作成される。またBSD互換のsocket()関数を使用して作成されたソケットは、既定でWSA_FLAG_OVERLAPPED属性を持つ。 設計目標は、UNIXから Windows へのソケットベースのアプリケーションの移植を容易にすることであった。新たに Windows 向けに書かれるプログラムにとって、そのAPIが十分かどうかはあまり考慮されなかった。このため、Winsock には移植のために設計された要素がいくつか含まれている。例えば、UNIXアプリケーションでは、ネットワークのエラーも標準Cライブラリの関数内のエラーも同じ errno で表される。これは Windows にはない機能であるため、Winsock はそのための関数 WSAGetLastError() でエラー情報が得られるようにした。このような機能は役立つものの、アプリケーションの移植はなかなか困難だった。多くのTCP/IPアプリケーションは、仮想端末とかforkシステムコールといったUNIXのシステム固有機能を使って実装されており、そのような機能を Windows で再現するのが困難だったのである。しかし、間もなく移植よりも Windows 独自のアプリケーション開発の方が主流となっていった。 Version 1.0 （1992年6月） Winsock の基本定義。BSDのソケットのインタフェースをかなり忠実に守っており、既存アプリケーションの移植性を考慮している。Windows固有の拡張が若干あり、主にメッセージ通知による非同期操作に関するものである。文書ではTCP/IPに制限してはいないが、具体的に言及されているプロトコルはTCPとUDPだけであった。ほとんどのベンダーはTCP/IPだけをサポートしたが、DECは DECnet もサポートしていた。 Verison 1.1 （1993年1月） 細かな修正と仕様の分類。重要な変更点としては、gethostname() 関数を追加した点が挙げられる。 Winsock 2 Winsock 1.1 との互換性を維持しつつ拡張している。プロトコルに独立した名前解決法をサポート。イベント通知や完了ルーチンによる非同期操作サポート。階層型プロトコル実装サポート。マルチキャスト。Quality of Service。複数プロトコルサポートも公式化され、IPX/SPXとDECnetが明記された。プロセス間でのソケット共有、コネクションの条件付き受理、ソケットグループ処理などが可能となった。Winsock 1.x とは大幅な違いがあるが、Winsock 1.1 API とのソース互換とバイナリ互換を保っている。他にも Service Provider Interface (SPI) API や Layered Service Provider (LSP) がサポートされた。 Version 2.0.x （1994年3月以降） 内部ドラフト。標準として公開されたものではない。 Version 2.1.0 （1996年1月） Winsock 2 としての最初の公開版。 Version 2.2.0 （1996年5月） 細かな修正、明確化、使用方法の追記など。16ビット Windows アプリケーションサポートを削除した。 Version 2.2.1 （1997年5月）、Version 2.2.2 （1997年8月） 細かな機能強化。ネットワーク構成やシステム構成の変化に関して問い合わせたり、通知を受け付ける機構を追加した。 IPv6対応はWindows 2000（2000年12月）で、RFC 2553 （後に RFC 3493 に置換）に基づいて行われ、Windows XPの Winsock の一部となっている。 マイクロソフトは Winsock 1.0 の実装を提供しなかった。 Winsock 1.1 は Windows for Workgroups のアドオンパッケージとして提供された。また、Windows 95 と Windows NT 3.x では最初から必須コンポーネントとして導入された。 Winsock 2 は Windows 95 のアドオンパッケージとして提供された。Windows 98および NT 4.0 以降は必須コンポーネントとして導入されている。Windows 3.x や NT 3.x 向けに Winsock 2 が提供されることはなかった。 Winsock 2.x は新たなWindowsのリリース時点やサービスパックの形で提供されている。 Winsock 2 は Layered Service Provider (LSP) と呼ばれる機構で拡張可能である。Winsock LSP はペアレンタル制御、Webコンテンツのフィルタリング、QoSなどに使われている。全ての Provider の階層順位は Winsock Catalog で管理される。かつて、バグのある LSP を削除すると Winsock Catalog が破壊されてネットワークが全く使えなくなるという問題があった。Windows XP SP2、Windows Server 2003 SP1、およびその後の Windows では、LSP をアンインストールしても自動修復できるようになっている。 Winsock 準拠の TCP/IP スタックを提供するベンダーとしては、スリーコム、Beame & Whiteside、DEC、Distinct、FTP Software、Frontier、IBM、Microdyne、NetManage、ノベル、サン・マイクロシステムズ、Trumpet Software International などがある。 Trumpet Winsock は数少ない Winsock 1.0 の実装であり、Windows 3.0 にインストール可能であった。Trumpet は Windows 3.x 向け Winsock のシェアウェア版でも知られている。2008年2月以降はTattam Software EnterprisesがTrumpet の知的所有権を有している。 ^ SOL_SOCKET Socket Options (Winsock2.h) - Win32 apps | Microsoft Docs ^ Blocking Input/Output - Win32 apps | Microsoft Docs ^ Default State for a Socket's Overlapped Attribute - Win32 apps | Microsoft Docs ^ マイクロソフト (2007年5月28日). “Windows 95 用の Windows Sockets 2.0 について”. サポート技術情報. 2016年10月18日閲覧。 ^ Tattam Software Enterprises 公式サイト Aboba, Bernard D., comp.protocols.tcp-ip.ibmpc, Frequently Asked Questions, 1993. Usenet: news:news.answers. この記事は2008年11月1日以前にFree On-line Dictionary of Computingから取得した項目の資料を元に、GFDL バージョン1.3以降の「RELICENSING」(再ライセンス) 条件に基づいて組み込まれている。 ソケット (BSD) Windows Sockets - Winsock のオープンソース実装(リンク切れ) Windows Sockets - Winsock のオープンソース実装(上記リンクの2009年2月のスナップショット) Sockets FAQ - Windows Sockets FAQ Windowns Sockets 2.0 MSDNライブラリ - Winsock2 Reference MSDNライブラリ - Winsock2 Home Porting Berkley Socket programs to Winsock Brief History of Microsoft on the Web WinSock Development Information Winsock Programmer's FAQ Komodia Inc. free open-source windows based Winsock library