サンプル集  >  VC  >  winsock2
winsock2
2010/01/05

winsock2 を使って通信するプログラムを作ります。

◆環境
OS Windows XP Professional Version 2002 Service Pack 3
VC Microsoft Visual Studio 2008 Version 9.0.30729.1 SP

Visual Studio 2008 Express にもまだ慣れていないので、起動直後から1つづつ進めてみます。

起動直後は空っぽです。

[ファイル(F)]-[新規作成(N)]-[プロジェクト(P)...]を選択します。

「新しいプロジェクト」ダイアログが開くので、以下の内容を入力します。

プロジェクトの種類(P)CLR
テンプレート(T)CLR コンソール アプリケーション
プロジェクト名(N)winsock2TestServer
場所(L)C:\
ソリューション名(M)winsock2Test

入力後、「OK」を押下します。

ソリューション「winsock2Test」と、その中に「winsock2TestServer」プロジェクトが作成されました。

まずはサーバー側のプログラムを作ります。

winsock2TestServer.cpp
  1: 
  2: 
  3: 
  4: 
  5: 
  6: 
  7: 
  8: 
  9: 
 10: 
 11: 
 12: 
 13: 
 14: 
 15: 
 16: 
 17: 
 18: 
 19: 
 20: 
 21: 
 22: 
 23: 
 24: 
 25: 
 26: 
 27: 
 28: 
 29: 
 30: 
 31: 
 32: 
 33: 
 34: 
 35: 
 36: 
 37: 
 38: 
 39: 
 40: 
 41: 
 42: 
 43: 
 44: 
 45: 
 46: 
 47: 
 48: 
 49: 
 50: 
 51: 
 52: 
 53: 
 54: 
 55: 
 56: 
 57: 
 58: 
 59: 
 60: 
 61: 
 62: 
 63: 
 64: 
 65: 
 66: 
 67: 
 68: 
 69: 
 70: 
 71: 
 72: 
 73: 
 74: 
 75: 
 76: 
 77: 
 78: 
 79: 
 80: 
 81: 
 82: 
 83: 
 84: 
 85: 
 86: 
 87: 
 88: 
 89: 
 90: 
 91: 
 92: 
 93: 
 94: 
 95: 
 96: 
 97: 
 98: 
 99: 
100: 
101: 
102: 
103: 
104: 
105: 
106: 
107: 
108: 
// winsock2TestServer.cpp : メイン プロジェクト ファイルです。

#include "stdafx.h"
#include "winsock2.h"
#include <iostream>
using namespace std;

using namespace System;

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

int main(array<System::String ^> ^args)
{
    WSADATA wsaData;
    int     ret;
    SOCKET  sock;
    int     len;
    SOCKET  client_sock;

    struct sockaddr_in addr;
    struct sockaddr_in client;

    // winsock2の初期化
    ret = WSAStartup( MAKEWORD( 2, 0 ), &wsaData );
    if ( ret != 0 )
    {
        switch( ret )
        {
        case WSASYSNOTREADY:
            printf( "WSASYSNOTREADY\n" );
            break;
        case WSAVERNOTSUPPORTED:
            printf( "WSAVERNOTSUPPORTED\n" );
            break;
        case WSAEINPROGRESS:
            printf( "WSAEINPROGRESS\n" );
            break;
        case WSAEPROCLIM:
            printf( "WSAEPROCLIM\n" );
            break;
        case WSAEFAULT:
            printf( "WSAEFAULT\n" );
            break;
        default:
            break;
        }
        exit( -1 );
    }
    printf( "WSAStartup successful.\n" );

    // ソケットの作成
    sock = socket( AF_INET, SOCK_STREAM, 0 );
    if ( sock == INVALID_SOCKET )
    {
        printf( "error : %d\n", WSAGetLastError() );
        exit( -2 );
    }
    printf( "socket successful.\n" );

    // ソケットの設定
    addr.sin_family = AF_INET;
    addr.sin_port = htons( 12345 );
    addr.sin_addr.S_un.S_addr = INADDR_ANY;
    ret = bind( sock
              , ( struct sockaddr* )&addr
              , sizeof( addr )
              );
    if ( ret == SOCKET_ERROR )
    {
        printf( "error : %d\n", WSAGetLastError() );
        exit( -3 );
    }
    printf( "bind successful.\n" );

    // TCPクライアントからの接続要求を待てる状態にする
    // 接続数は5
    ret = listen( sock, 5 );
    if ( ret == SOCKET_ERROR )
    {
        printf( "error : %d\n", WSAGetLastError() );
        exit( -4 );
    }
    printf( "listen successful.\n" );

    // TCPクライアントからの接続要求を受け付ける
    len = sizeof( client );
    client_sock = accept( sock
                        , ( struct sockaddr* )&client
                        , &len
                        );
    printf( "accepted connection from %s (%d)\n"
          , inet_ntoa( client.sin_addr )
          , ntohs( client.sin_port )
          );

    // メッセージ送信
    char* msg = "HELLO winsock2!!";
    send( client_sock, msg, strlen( msg ), 0 );

    // TCPセッションの終了
    closesocket( client_sock );

    // winsock2の終了処理
    WSACleanup();
    printf( "WSACleanup successful.\n" );

    return 0;
}

コンパイルが通ったのでとりあえずサーバー側は置いておいて、クライアント側を作ります。 クライアントは別プロジェクトにしたいと思います。

[ファイル(F)]-[新規作成(N)]-[プロジェクト(P)...]を選択します。

「新しいプロジェクト」ダイアログが開くので、以下の内容を入力します。

プロジェクトの種類(P)CLR
テンプレート(T)CLR コンソール アプリケーション
プロジェクト名(N)winsock2TestClient
場所(L)C:\winsock2Test
ソリューション(S)ソリューションに追加
ソリューション名(M)<入力不可>

入力後、「OK」を押下します。

ソリューション「winsock2Test」に「winsock2TestClient」プロジェクトが追加されました。

クライアントのプログラムを作ります。

winsock2TestClient.cpp
 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
49: 
50: 
51: 
52: 
53: 
54: 
55: 
56: 
57: 
58: 
59: 
60: 
61: 
62: 
63: 
64: 
65: 
66: 
67: 
68: 
69: 
70: 
71: 
72: 
73: 
74: 
75: 
76: 
77: 
78: 
79: 
80: 
81: 
82: 
83: 
84: 
85: 
86: 
87: 
88: 
89: 
// winsock2TestClient.cpp : メイン プロジェクト ファイルです。

#include "stdafx.h"
#include "winsock2.h"
#include <iostream>
using namespace std;

using namespace System;

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

int main(array<System::String ^> ^args)
{
    WSADATA wsaData;
    int     ret;
    SOCKET  sock;
    char    buf[32];

    struct sockaddr_in server;

    ret = WSAStartup( MAKEWORD( 2, 0 ), &wsaData );
    if ( ret != 0 )
    {
        switch( ret )
        {
        case WSASYSNOTREADY:
            printf( "WSASYSNOTREADY\n" );
            break;
        case WSAVERNOTSUPPORTED:
            printf( "WSAVERNOTSUPPORTED\n" );
            break;
        case WSAEINPROGRESS:
            printf( "WSAEINPROGRESS\n" );
            break;
        case WSAEPROCLIM:
            printf( "WSAEPROCLIM\n" );
            break;
        case WSAEFAULT:
            printf( "WSAEFAULT\n" );
            break;
        default:
            break;
        }
        exit( -1 );
    }
    printf( "WSAStartup successful.\n" );

    sock = socket( AF_INET, SOCK_STREAM, 0 );
    if ( sock == INVALID_SOCKET )
    {
        printf( "error : %d\n", WSAGetLastError() );
        exit( -2 );
    }
    printf( "socket successful.\n" );

    // 接続先指定用構造体の準備
    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 )
           );

    // サーバからデータを受信
    memset( buf, 0, sizeof( buf ) );
    int n = recv( sock, buf, sizeof( buf ), 0 );
    if ( n == SOCKET_ERROR )
    {
        switch( WSAGetLastError() )
        {
        case WSAENOTCONN:
            printf( "ソケットが接続されていません。\n" );
            exit( -10 );
        default:
            printf( "error : %d\n", WSAGetLastError() );
            exit( -11 );
        }
    }
    printf( "%d, %s\n", n, buf );

    // winsock2の終了処理
    WSACleanup();
    printf( "WSACleanup successful.\n" );

    return 0;
}

早速、実行してみましょう。 まずはDOS窓でサーバー側を実行します。

◆サーバー側
C:\winsock2Test\Debug> winsock2TestServer.exe
WSAStartup successful.
socket successful.
bind successful.
listen successful.

サーバー側を実行すると、accept で待ち状態になります。 この状態で別のDOS窓を起動し、クライアント側を実行します。

◆クライアント側
C:\winsock2Test\Debug> winsock2TestClient.exe
WSAStartup successful.
socket successful.
16, HELLO winsock2!!
WSACleanup successful.

無事、サーバーに接続し「HELLO winsock2!!」というメッセージを受信しました。

サーバー側にも accept のメッセージが出ました。

◆サーバー側
accepted connection from 127.0.0.1 (1479)
WSACleanup successful.

とりあえず通信ができました!

プログラムに IP、ポートが直書きなのでこれを ini ファイルに出したいと思います。

>> 続き

▲ PageTop  ■ Home


Copyright (C) 2012 ymlib.com