1472バイトを超えるUDPパケットの送受信が失敗してしまう(μNet3/Standard版)

弊社TCP/IPプロトコルスタック「μNet3」に関するご質問
返信する
アバター
eForce技術担当
記事: 193
登録日時: 2014年4月24日(木) 14:18

1472バイトを超えるUDPパケットの送受信が失敗してしまう(μNet3/Standard版)

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

本手順は、μNet3/Standard版のパッケージの手順となります。
μNet3/Compact版をご使用の場合、1472バイトを超えるUDPパケットの送受信が失敗してしまう(μNet3/Compact版)を参照ください。

65507バイト(※1)のUDPパケットの送受信など大きなフレームのやり取りをする場合は、
以下の手順を踏む事で実現する事が出来ます。
※1:20(IPヘッダ) + 8(UDPヘッダ) + 65507(ペイロード) = 65535

■ネットワークライブラリの再作成
ユーザが任意でネットワークバッファの確保処理やネットワークバッファの
大きさ、種類、それぞれの数を管理を行う機能を有効にするため以下の手順でμNet3ライブラリを再作成します。

1.「\Network\lib\CortexA\uNet3cortexa.eww」などのソリューションファイルをIDEで起動

2.コンパイル時のプリプロセッサ定義に「EXT_ALOC_SUP」を追加
EXT_ALOC_SUP_setting_1.png
3.全ライブラリプロジェクトにプリプロセッサ定義を追加し、リビルドを行う
EXT_ALOC_SUP_setting_2.png
EXT_ALOC_SUP_setting_2.png (12.71 KiB) 閲覧された回数 13520 回
EXT_ALOC_SUP_setting_3.png
4.「net_cfg.c」に以下の固定長メモリプールの定義を追加
#define NET_LARGE_BUF_CNT 2
#define NET_LARGE_BUF_SZ 65535 + 76

const T_CMPF c_net_mpf_65535 = {TA_TFIFO, NET_LARGE_BUF_CNT, NET_LARGE_BUF_SZ, NULL, NULL};
Net_Configguration_1.png
5.「net_cfg.c」に以下のネットワークバッファ拡張管理処理を追加
Net_Configguration_2.png
Net_Configguration_3.png

コード: 全て選択

ID ID_NET_MPF = -1;
ID ID_NET_MPF_65535 = -1;

ER net_memini(void)
{
    extern UW NET_BUF_SZ;
    ER ercd;
    
    NET_BUF_SZ = NET_LARGE_BUF_SZ;

    ercd = acre_mpf((T_CMPF *)&c_net_mpf);
    if ( ercd < 0 ) {
        ID_NET_MPF = -1;
        return ercd;
    }
    ID_NET_MPF = ercd;
    
    ercd = acre_mpf((T_CMPF *)&c_net_mpf_65535);
    if ( ercd < 0 ) {
        del_mpf(ID_NET_MPF);
        ID_NET_MPF = -1;
        return ercd;
    }
    ID_NET_MPF_65535 = ercd;
    
    return E_OK;
}

ER net_memext(void)
{
    if ( ID_NET_MPF > 0 ) {
        del_mpf( ID_NET_MPF );
    }
    if ( ID_NET_MPF_65535 > 0 ) {
        del_mpf( ID_NET_MPF_65535 );
    }
    return E_OK;
}

ER net_memget(VP *adr, UINT len, TMO tmo, ID *id)
{
    if ( len > NET_BUF_SZ ) {
        return E_NOMEM;
    }

    if ( len > CFG_NET_BUF_SZ ) {
        *id = ID_NET_MPF_65535;
    } else {
        *id = ID_NET_MPF;
    }
    return tget_mpf( *id, adr, tmo );
}

ER net_memret(VP adr, ID id)
{
    return rel_mpf( id, adr );
}
6.65507バイトのパケットを送信するテストコードを追加
sample_test_1.png

コード: 全て選択

    {
        SID sid;
        T_NODE host = { 0 };
        T_NODE remote = { 0 };
   
        host.num  = DEV_ANY;
        host.ver  = IP_VER4;
        host.ipa  = INADDR_ANY;
        host.port = 10000;
        sid = (SID)cre_soc( IP_PROTO_UDP, &host );

        remote.ver = IP_VER4;
        remote.num = 1;     /* ネットワークデバイス番号 */
        remote.ipa = ip_aton( "172.16.0.14" );
        remote.port = 12345;

        ercd = con_soc( sid, &remote, 0 );
        ercd = snd_soc( sid, &buf[0], 65507 );

        slp_tsk();
    }
7.Wireshark上で正常にパケットが送信されている事を確認
sample_test_2.png
8.65507バイトのパケットを受信するテストコードを追加
sample_test_3.png

コード: 全て選択

    {
        SID sid;
        T_NODE host = { 0 };
        T_NODE remote = { 0 };
   
        host.num  = DEV_ANY;
        host.ver  = IP_VER4;
        host.ipa  = INADDR_ANY;
        host.port = 10000;
        sid = (SID)cre_soc( IP_PROTO_UDP, &host );

        ercd = rcv_soc( sid, &buf[0], sizeof(buf) );
        
        slp_tsk();
    }
9.65507バイトのパケットが受信される事を確認
sample_test_4.png
■補足
サンプルプログラムでは、net_cfg.hで定義される標準ネットワークバッファの数を
以下のように定義しています。

#define CFG_NET_BUF_CNT 91

「91」という数字の内訳は「45 + 45 + 1」となっており、詳細としては以下の様になっています。
45 = IPフラグメント受信(分割パケット)の最大発生を想定した数
45 = IPフラグメント送信(分割パケット)の最大発生を想定した数
1 = ARPパケットで最低限必要なネットワークバッファの数

ただ、上記の数値は瞬間的に必要とされる理論値(最大値)なのでアプリケーションの設計に応じて適宜変更してください。
※最低45 + 1あれば、65507バイトのパケットの送受信を行う事が可能です。

返信する