Server と Client で通信

DOS モードで TCP(Transmission Control Protocol) Server に Client から接続します。

Server は Client からの接続を待ちます。
TCP クライアントからの接続要求を待っています
Client は Server からメッセージを受信して表示します。
5 はメッセージ長です。
5,HELLO

前田稔(Maeda Minoru)の超初心者のプログラム入門

Server プロジェクト

  1. Server 側のプログラムの手順です。
    Server はセッションを開設して Client からの接続を待ちます。
    1. ソケットを作る
    2. IP アドレスとポートを設定する
    3. bind する
    4. 接続待ち状態で待機する
    5. Client からの接続を受け付ける
    6. Client にメッセージを送信する
    7. 送信が終われば終了する
  2. Win32 コンソールアプリケーションを作成して Server の main.cpp をプロジェクトに追加します。
  3. winsock2.h をインクルードして ws2_32.lib をリンクしなければならないのですが #pragma でリンクするので特に操作は不要です。
  4. プロジェクトをビルドして Server の Main.exe を作成して下さい。


Client プロジェクト

  1. Client 側のプログラムの手順です。
    Client はセッションを開設している Server に接続してメッセージを受信します。
    1. ソケットを作る
    2. 接続相手を設定する
    3. Server に接続する
    4. メッセージを受信する
  2. Win32 コンソールアプリケーションを作成して Client の main.cpp をプロジェクトに追加します。
  3. winsock2.h をインクルードして ws2_32.lib をリンクしなければならないのですが #pragma でリンクするので特に操作は不要です。
  4. プロジェクトをビルドして Client の Main.exe を作成して下さい。

プログラムのテスト

  1. 最初に Server の Main.exe を起動します。
    Server が起動されると次のメッセージを表示して、TCP Client からの接続待ちの状態に入ります。
    printf("TCP クライアントからの接続要求を待っています\n");
  2. Server の起動を確認して Client の Main.exe を起動します。
  3. Client は Server から送られてきたメッセージ("HELLO") を表示して getch() で表示の確認を待ちます。
    何かキーをタイプすると Client が終了します。
  4. Server は Client にメッセージを送信するとすぐに終了します。
  5. ファイアウォールに付いては UDP でメッセージを送受信 を参照して下さい。

Server プログラムの説明

  1. WSAStartup() 関数で Winsock を初期化して、ソケットを作成します。
    この辺は Server も Client も同じです。
        int main()
        {   WSADATA wsaData;
            SOCKET  sock0;
            struct  sockaddr_in addr;
            struct  sockaddr_in client;
            int     len;
            SOCKET  sock;
    
            // winsock2 の初期化
            if (WSAStartup(MAKEWORD(2,0), &wsaData))
            {   printf("winsock の初期化に失敗しました\n");
                getch();
                return 1;
            }
    
            // ソケットの作成
            sock0= socket(AF_INET,SOCK_STREAM,0);
            if (sock0 == INVALID_SOCKET)
            {   printf("socket failed\n");
                getch();
                return 1;
            }
        
  2. ソケットを設定して Client からの接続要求を待ちます。
    ポート番号 12345 で待ち状態に入ります。
    listen(sock0, 5) の5は、接続を受け付けるキューの最大数です。
            // ソケットの設定
            addr.sin_family = AF_INET;
            addr.sin_port = htons(12345);
            addr.sin_addr.S_un.S_addr = INADDR_ANY;
            bind(sock0, (struct sockaddr *)&addr, sizeof(addr));
            printf("TCP クライアントからの接続要求を待っています\n");
            // TCPクライアントからの接続要求を待てる状態にする
            listen(sock0, 5);
        
  3. 接続要求があると、メッセージを送信して終了します。
    sock には、接続してきたクライアントサイドのソケット情報が格納されます。
            // TCP クライアントからの接続要求を受け付ける
            len = sizeof(client);
            sock = accept(sock0, (struct sockaddr *)&client, &len);
            // 5文字送信
            send(sock, "HELLO", 5, 0);
            // TCP セッションの終了
            closesocket(sock);
            // winsock2 の終了処理
            closesocket(sock0);
            WSACleanup();
            return 0;
        }
        

Client プログラムの説明

  1. WSAStartup() 関数で Winsock を初期化して、ソケットを作成します。
    この辺は Server も Client も同じです。
        int main()
        {   WSADATA wsaData;
            struct  sockaddr_in server;
            SOCKET  sock;
            char    buf[32];
    
            // winsock2の初期化
            if (WSAStartup(MAKEWORD(2,0), &wsaData))
            {   printf("winsock の初期化に失敗しました\n");
                getch();
                return 1;
            }
    
            // ソケットの作成
            sock= socket(AF_INET,SOCK_STREAM,0);
            if (sock == INVALID_SOCKET)
            {   printf("socket failed\n");
                getch();
                return 1;
            }
        
  2. 接続先指定用構造体を設定して connect() でサーバーに接続します。
    "127.0.0.1" が IP アドレスで、12345 はポート番号です。
            // 接続先指定用構造体の準備
            server.sin_family = AF_INET;
            server.sin_port = htons(12345);
            server.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
            // サーバーに接続
            connect(sock, (struct sockaddr *)&server, sizeof(server));
        
  3. Server から受け取ったメッセージとバイト数を表示して WSACleanup() で終了します。
            // サーバーからデータを受信
            memset(buf,0,sizeof(buf));
            int n = recv(sock,buf,sizeof(buf),0);
            printf("%d,%s\n",n,buf);
            closesocket(sock);
    
            // winsock2 の終了処理
            WSACleanup();
            getch();
            return 0;
        }
        

ソースプログラムです。 (^_^;)
ファイル名 説明
TCPServer\Main.cpp Server のソースコード
TCPClient\Main.cpp Client のソースコード

超初心者のプログラム入門(Win32API C++)