ホーム > デベロッパ > SophiaFramework > BREW C++ 逆引きコード集

BREW C++ プログラミング : SophiaFramework 逆引き FAQ・コード集

TCP ソケット通信を行う方法

SFXTCPSocket クラスを利用して、TCP ソケット通信を行います。

// TCP ソケット 通信に必要な SFXTCPSocket クラスのインスタンス _tcp はクラスのメンバ変数として定義する
class NetworkTime {
private:
    SFXTCPSocket _tcp;
    SFXBinaryStreamReader _reader;

public:
    Void Start(Void); // NTP サーバーとの接続を開始する
    Void Stop(Void);  // 接続途中で NTP サーバーとの接続を終了する
    
    // コールバック関数の宣言
    CALLBACK_DECLARE_SFXTCPSOCKET(OnConnect)
    CALLBACK_DECLARE_SFXBINARYSTREAMREADER(OnFetch)
};

// NTP サーバーとの接続を開始する
Void NetworkTime::Start(Void)
{
    SFCError error(SFERR_NO_ERROR);
    // NTP サーバーのアドレスを設定する
    SFXSocketAddress address("www.example.com:37");

    // NTP サーバーとの接続を初期化する
    if ((error = _tcp.Open()) == SFERR_NO_ERROR) {

        // NTP サーバーに接続する
        if ((error = _tcp.Connect(address,
                CALLBACK_FUNCTION(OnConnect))) == SFERR_NO_ERROR) {
            ...
        }
        else {
            // エラーが発生したとき
            _tcp.Close();
        }
    }
	
    if (error != SFERR_NO_ERROR) { 
        // エラーが発生したとき
        // エラー処理
        ...
    }
    return;
}

// 接続途中で NTP サーバーとの接続を終了する場合に呼び出す
Void NetworkTime::Stop(Void)
{
    // 終了処理
    _reader.Release();
    _tcp.Close();
    return;
}

// 接続が確立したときに呼び出されるコールバック関数
CALLBACK_IMPLEMENT_SFXTCPSOCKET(NetworkTime, OnConnect, error)
{
    if (error == SFERR_NO_ERROR) {

        // データ受信用ストリームを取得する
        if ((error = _tcp.GetStreamReader(64, &_reader)) == SFERR_NO_ERROR) {

            // フェッチ(データ受信)する
            // 4 バイトのデータを受信すると、OnFetch 関数に通知される
            if ((error = _reader.Fetch(4, CALLBACK_FUNCTION(OnFetch)))
                == SFERR_NO_ERROR) {
                ...
            }
            if (error != SFERR_NO_ERROR) { 
                // エラーが発生したとき
                _reader.Release();
            }
        }
    }
	
    if (error != SFERR_NO_ERROR) {  
        // エラーが発生したとき
        _tcp.Close();
    }
    return;
}

// フェッチ(データ受信)が完了したときに呼び出されるコールバック関数
CALLBACK_IMPLEMENT_SFXBINARYSTREAMREADER(NetworkTime, OnFetch, error)
{
    SFXDate date; // 日付クラス
    UInt32 time;

    if (error == SFERR_NO_ERROR) {

        // データをビッグ エンディアンとして読み込む設定をする
        _reader.SetEndian(SFXBinaryStreamReader::ENDIAN_BIG);
        
        // データを UInt32 型として読み込み、time 変数に格納する
        if ((error = _reader.ReadUInt32(&time)) == SFERR_NO_ERROR) {
            
            // 日付クラスに取得した時刻 ( 秒 ) を設定する
            date.Set(time);
            
            // 受信したデータは 1900 年 1 月 1 日 からの時刻なので調整する
            date -= SFXDateDuration::Offset19000101();
            
            // 時刻をローカル時刻に変換する
            date += SFXDateDuration::LocalTimeOffset();

            // 時刻を書式に合わせて出力する
            TRACE("%s", date.Format("YYYY/MM/DD hh:mm:ss").GetCString());
        }
    }
	
    if (error != SFERR_NO_ERROR) {
        // エラーが発生したとき
        // エラー処理
        ...
    }

    // 終了処理
    _reader.Release();
    _tcp.Close();
    return;
}