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

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

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

SFXUDPSocket クラスを利用して UDP ソケット通信を行います。

// UDP ソケット通信に必要な SFXUDPSocket クラスのインスタンス _socket はクラスのメンバ変数として定義する
class MyClass {
private:
    SFXUDPSocket _socket;

public:
    Void Start(Void);

    // コールバック関数
    CALLBACK_DECLARE_SFXUDPSOCKET(OnBind)
    CALLBACK_DECLARE_SFXUDPSOCKET(OnSend)
    CALLBACK_DECLARE_SFXUDPSOCKET(OnReceive)
};

Void MyClass::Start(Void)
{
    SFCError error;

    // ソケットを開く
    if ((error = _socket.Open()) == SFERR_NO_ERROR) {

        // ソケットをローカル の IP アドレスとポート番号にバインドする
        OnBind(SFERR_NO_ERROR);
    
    }
    return;
}

// バインド用のコールバック関数
CALLBACK_IMPLEMENT_SFXUDPSOCKET(MyClass, OnBind, error)
{
    SFXSocketAddress address(SFXInetAddress::LoopbackInetAddress(), 1024);

    // エラーが発生したかどうかチェックする
    if (error == SFERR_NO_ERROR) {

        error = _socket.Bind(address);

        switch (error) {
            case SFERR_NO_ERROR:

                // データを非同期に書き込む
                OnSend(SFERR_NO_ERROR);
                break;
            case AEE_NET_WOULDBLOCK:

                // コールバック関数を登録する
                _socket.ScheduleBind(CALLBACK_FUNCTION(OnBind));
                break;
        }
    }
    return;
}

// 送信用のコールバック関数
CALLBACK_IMPLEMENT_SFXUDPSOCKET(MyClass, OnSend, error)
{
    static ACharConst data[] = "udp!";
    SFXSocketAddress address(SFXInetAddress::LoopbackInetAddress(), 1024);
    UInt32 size;

    // エラーが発生したかどうかチェックする
    if (error == SFERR_NO_ERROR) {
        size = sizeof(data) - 1;

        // データを非同期的に送信する
        error = _socket.Send(address, data, &size);

        switch (error) {
            case SFERR_NO_ERROR:

                // 指定したサイズのデータが書き込まれたかチェックする
                // Send 関数は指定したサイズのデータを
                // 一度に書き込めないことがある
                // その場合、ここでは簡易化のためエラーとしている
                if (size == sizeof(data) - 1) {

                    // データを非同期に読み込む
                    OnReceive(SFERR_NO_ERROR);
                }
                else {
                    TRACE("...send failed...");
                }
                break;
            case AEE_NET_WOULDBLOCK:

                // コールバック関数を登録する
                _socket.ScheduleSend(CALLBACK_FUNCTION(OnSend));
                break;
        }
    }
    return;
}

// 受信用のコールバック関数
CALLBACK_IMPLEMENT_SFXUDPSOCKET(MyClass, OnReceive, error)
{
    SFXSocketAddress socket;
    SFXBuffer buffer;
    UInt32 size;

    // エラーが発生したかどうかチェックする
    if (error == SFERR_NO_ERROR) {
        buffer.SetSize(4);

        size = static_cast(buffer.GetSize());

        // 非同期的にデータを受信する
        switch (_socket.Receive(&socket, buffer.GetBuffer(), &size)) {
            case SFERR_NO_ERROR:

                // 指定したサイズのデータが読み込まれたかチェックする
                // Receive 関数は指定したサイズのデータを
                // 一度に読み込めないことがある
                // その場合、ここでは簡易化のためエラーとしている
                if (size == buffer.GetSize()) {

                    // 読み込んだデータを表示する
                    buffer.SetSize(buffer.GetSize() + 1);
                    buffer[buffer.GetSize() - 1] = '\0';
                    TRACE(":%s", SFXAnsiString(buffer).GetCString());

                    // ソケットを閉じる
                    _socket.Close();
                }
                else {
                    TRACE("...receive failed...");
                }
                break;
            case AEE_NET_WOULDBLOCK:

                // コールバック関数を登録する
                _socket.ScheduleReceive(CALLBACK_FUNCTION(OnReceive));
                break;
        }
    }
    return;
}