WinSock/初心者むけの全体像

出典: フリー教科書『ウィキブックス(Wikibooks)』
ナビゲーションに移動 検索に移動

導入の方法[編集]

基本[編集]

ウィンドウズのVisual C++などマイクロソフト製プログラミング言語を使ってネットワーク通信プログラミングをするには、Winsockをインクルードしなければならない。

なお、Winsockを使うにも、原則として Visual Studio が必要である。

まず、2020年の時点で、下記のような仕様である(実機で確認)。(※ ネットにあるサイトの情報が古いので(2001年くらいのとか平気である)、2020年代の現代では実機で確認の必要がある。)

2020年代でも、 Visual Studio でWinSockプログラミングを開発できる。(けっしてリナックスのGCC(Windows版でMinGWというのがある)などでは、普通の方法ではコンパイルできない。なので、Winsockアプリは Visual Studio で普通は開発しなければいけない。)

まず、Visual Studio で立ち上げるコード種類を選ぶ際には、Visual Studio の普通のC言語用のコンソールアプリケーションでよい。つまり、よく学校教育とかのC言語の授業の Hello World とかの入門で使う、普通のアレでいい。(Win32デスクトップアプリケーション用のは、立ち上げなくていい。)


MinGWは現状ではソケットと互換性が悪い[編集]

ネット上にはMinGWでWinSockコードをコンパイルした事例なども紹介されているが、たとえば

g++ -lwsock32 ファイル名.cpp -lws2_32

などのコマンドが各所のサイトに紹介されているが、しかし2020年現在、IPv6 関連の関数の一種である inet_pton()inet_ntopなど新しい関数がMinGWにあ対応しておらず、そのため、それらの関数を用いているコードの場合、Visual Studio コンパイルできたコードがMingWではコンパイルできない。

ちなみに、上記のg++コマンドではリンクオプションの-lを用いており、 「-lwsock32」とは「リンカwsock32をコンパイル時にリンクしろ」という意味。


通信の全体像[編集]

ソケット通信は、Windowsに限らずUnixなどでも一般に、通信の工程が下記のように分類されます。

WSAなんとかという用語は Winsock だけの用語ですが、それ以外のbindやsendなどの用語は、Unixソケット通信でも共通です。




   サーバー側        クライアント側   
ソケットの起動と初期化        WSAStartup WSAStartup
ソケットにアドレス登録 bind
クライアントからの通信待ち listen
クライアントがサーバに接続 ↓ ------------------------- connect
受付可能の状態でサーバ待機 accept -------------------------
データ送受信 send() / receive() -------------- send() / receive()
データ送受信の停止 shutdown shutdown
通信の切断 closesocket closesocket
ソケットの除去 WSACleanup WSACleanup

コードの概要[編集]

基本骨格のコード[編集]

Winsockプログラムでの典型的な基本骨格は、下記のようになります。

#include <stdio.h>
#include <winsock2.h>

#pragma comment(lib,"ws2_32.lib")

int main(){
	WSADATA wsaData;

	WSAStartup(2, &wsaData);

	WSACleanup();

	return 0;
}


これだけだと、単にWinsockを起動するだけなので、何も通信しないし表示しません。

このコードをもとに、これからコードをどんどん追加していって、必要なコードを加えていくことになります。


さて、Winsockでは、組み込み関数がいくつか既に予約されている。たとえば

WSAStartup は、WinSockの初期化のための関数であり、この関数の使い方も既に決まっている。

なお、WSAStartup関数で必要な設定を定義するために、事前にWSADATA 型 の変数の設定が必要である。


WSAStartup の1番目の変数の内容は、使用するWinsockのバージョンの指定です。とりあえず「2」を入れておけば、問題ありません(実機で確認ずみ)。

WSAStartup の2番目の変数の内容は、この処理内容を入れるためのWSADATA型変数の指定です。

なのでイメージ的には、まず

WSADATA data;
WSAStartup(バージョン指定,&data)

のように宣言をすることになる。


関数 WSACleanupは、WinSockを終了させる組み込み関数です。


導入部の説明[編集]

さて、Winsockのコードは、どのコードでも、まず、

#include <winsock2.h>

のようにコードの冒頭で winsock2.h をインクルードする記述が必要になる。もう何年も前からwinsockのバージョンが 2.x なので、2020年代でも引き続き、インクルードするのは winsock2.h で良い。なお、2020年の現時点では、Winsockは普通はバージョン2.2である(実機で確認ずみ)。

また、ライブラリ 「ws2_32.lib」も必要なので、下記のように pragma 演算子でライブラリ導入する必要がある。このライブラリを導入しないと(つまり下記のpragma文が無いと)、コンパイルしようとしてビルドボタンを押してもエラーになる。

結局、

#include <stdio.h>
#include <winsock2.h>

#pragma comment(lib,"ws2_32.lib")

のように冒頭で宣言することになる(ひとまず、コレだけでも動作が可能である)。

たとえば外部リンクのウィズダムソフトのコード例も、この冒頭の宣言を加えるだけで2020年代でも動作する(実機で確認ずみ)。

なお、2020年の現時点でも、Winsockはバージョン2.2であるので、インクルードするのは winsock2 で良い。


なお、最終的にサーバ側のプログラムでも、クライアント側のプログラムでも、それぞれwinsockをインクルードすることになる。