uNet3/CompactでのノンブロッキングTCPサーバサンプル(uNet3/Compact)

返信する
アバター
eForce技術担当
記事: 193
登録日時: 2014年4月24日(木) 14:18

uNet3/CompactでのノンブロッキングTCPサーバサンプル(uNet3/Compact)

投稿記事 by eForce技術担当 » 2016年7月04日(月) 17:58

対象:
μNet3/Compact

概要:
本項では、μNet3/Compactでノンブロッキングソケットを使用した、
TCPサーバの実装例を記載します。

前提条件:
SocketTask1タスクのタスクIDはID_TASK_SOC1に定義されている事とする。
下記サンプルの「SocketTask1」タスクの初期状態は休止状態である事とする。

コード: 全て選択

// ノンブロッキング用のコールバック関数
static ER tcp_server_callback(SID sid, UH event, ER err)
{
    // 接続完了通知
    if ( event & EV_SOC_CON ) {
        if ( err != E_OK ) {
            // 接続処理エラー(タイムアウトやキャンセルなど)
            return err;
        }
        sta_tsk( ID_TASK_SOC1, (VP_INT)sid );
    }

    // 送信完了通知
    if ( event & EV_SOC_SND ) {
    }

    // 受信完了通知
    if ( event & EV_SOC_RCV ) {
    }

    // 切断完了通知
    if ( event & EV_SOC_CLS ) {
    }

    return err;
}

// メインタスク
void MainTask(VP_INT exinf)
{
    ER ercd;
    UW evptn;
    T_NODE local;

    // uNet3初期化
    ercd = net_setup();
    if ( ercd != E_OK ) {
        return;
    }

    // evptn = EV_SOC_CON | EV_SOC_CLS | EV_SOC_SND | EV_SOC_RCV;
    // ※複数のノンブロッキング設定をしたい場合は上記の様に設定

    // 接続処理のみノンブロッキング処理させる
    evptn = EV_SOC_CON;

    // コールバック関数登録およびノンブロッキング設定
    cfg_soc( ID_SOC1, SOC_CBK_HND, (VP)tcp_server_callback );
    cfg_soc( ID_SOC1, SOC_CBK_FLG, (VP)evptn );

    // ノンブロッキングで接続要求(accept)
    local.ver = IP_VER4;
    local.num = DEV_ANY;
    local.ipa = INADDR_ANY;
    local.port = htons( 10000 );

    ercd = con_soc( ID_SOC1, &local, SOC_SER );
    if ( ercd != E_WBLK ) {
        // ノンブロッキング処理失敗
        return;
    }

    slp_tsk();
}

// テスト用タスク
void SocketTask1(VP_INT exinf)
{
    SID sid = 0U;
    ER ercd = 0;
    VB buf[16];

    sid = (SID)exinf;

    // 受信処理
    ercd = rcv_soc( sid, buf, sizeof(buf) );
    if ( ercd <= 0 ) {
        // ercd = 0の場合は対向から切断された。それ以外はエラー
    }


    cls_soc( sid, SOC_TCP_CLS );

    return;
}
上記の実装例以外にも、SocketTask1タスク内でメールボックスの受信待ちにしておき、
コールバック関数内でのイベントに応じたイベントメッセージを構築して、受信待ちしている
SocketTask1タスクにイベントメッセージを送信するというような実装方法も考えられます。

また、送信完了や受信完了をタスクへ通知する場合はイベントフラグなどを使用する事で実現出来ます。

返信する