クライアントは、次のような作法で作ることができます。
ソケットの作成
↓
接続
↓
送受信
↓
切断
↓
接続
↓
送受信
↓
切断
ソケットの作成
サーバと接続、通信を行うためのソケットを作成します。
接続
使用するソケットと接続先の情報(アドレスとポート番号)を指定して、接続要求を行います。
接続先であるサーバが接続要求受信待ちでなければ、即失敗となります。
接続先であるサーバが接続要求受信待ちでなければ、即失敗となります。
送受信
ソケットを使って、送受信します。(接続先が一つに確定しているので、サーバのように新たに専用のソケットを作られるようなことはありません。複数のサーバと接続する場合は、ソケットの作成~切断までの手順を接続したいサーバの分だけ行えばよいです。)
切断
通信をやめる際に明示的にその旨を伝えるために行います。
そうしないとメモリなどの資源が使用されたままの状態になり、無駄が発生します。無駄が積み重なると有限である資源が枯渇することになります。
そうしないとメモリなどの資源が使用されたままの状態になり、無駄が発生します。無駄が積み重なると有限である資源が枯渇することになります。
サーバ同様、ここでコードを書きたいのですが、コードを書く前に環境を構築しましょう。
サーバのときと同様のプロジェクト作成手順を実施し、main.cppを追加するところまで行ってください。またリンカの設定(;ws2_32.libの追加もおこなってください。(「server」と入力していたところは「client」にしてください。)
クライアントプログラムを書くと以下のようになります。
#include <stdio.h> #include <winsock2.h> int main(int argc, char** argv) { WSADATA wsaData; struct sockaddr_in server; SOCKET commSock; char recvBuf[256]; int recvLen; printf("クライアントプログラムスタート\n"); // Winsock2 DLL 初期化 WSAStartup(MAKEWORD(2,0), &wsaData); printf("ソケットの作成\n"); commSock = socket(AF_INET, SOCK_STREAM, 0); // 接続先データの準備 server.sin_family = AF_INET; server.sin_port = htons(12345); server.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); printf("接続\n"); connect(commSock, (struct sockaddr *)&server, sizeof(server)); recvLen = recv(commSock, recvBuf, sizeof(recvBuf), 0); recvBuf[recvLen] = '\0'; printf("\"%s\"受信\n", recvBuf); printf("\"おはよう\"送信\n"); send(commSock, "おはよう", strlen("おはよう"), 0); printf("切断\n"); closesocket(commSock); // Winsock2 DLL 終了 WSACleanup(); return 0; }
上記プログラムは、
- 接続要求受信用ソケットを作成(socket())し、アドレスやポート番号などを指定し、接続(connect())します。
- その後、クライアントからのなんらかのメッセージが来るのを待ち、受信(recv())するとそのメッセージを表示(printf())します。
- メッセージ受信後、サーバに対して「おはよう」というメッセージを送信(send())します。
- 送信後、通信を切断(closesocket())し、プログラムは終了します。
サーバとクライアントを起動するには、Windowsのスタートメニューから「Microsoft Visual C++ 2010」を二つ起動し、一方でserverプロジェクトを、もう一方でclientプロジェクトを開いてください。
では実際に通信させてみましょう。
- serverプロジェクトで「デバッグなしで開始」を行います。
- コンソールが表示されてクライアントからの接続要求受付状態で待機します。ここまではサーバプログラミングで説明した内容と同じです。
- clientプロジェクトで「デバッグなしで開始」を行います。
- サーバ、クライアント、双方のコンソール状態は以下のようになります。
サーバのコンソール
クライアントのコンソール
どうでしょうか。「おはよう」を言い合うアプリケーションができました。
これがもっともシンプルな通信であり、基本はこれで抑えられたと考えていいと思います。
しかしながら、このぐらいの通信では、あまりにシンプルすぎて、使い道がありません。
もう少し複雑度を上げて、現実世界で応用が利くようにしていきたいと思います。
まずは、複数クライアントとの接続を実現していきましょう。>>複数クライアント接続対応って何?