簡単なサンプル

弊社TCP/IPプロトコルスタック「μNet3」に関する書込みはこちらにお願いします。
返信する
yys99
記事: 1
登録日時: 2014年8月29日(金) 10:57

簡単なサンプル

投稿記事 by yys99 » 2014年8月29日(金) 11:17

ネットワークプログラミングの初心者です。 :?:

アプリケーションのサンプルは読みずらいので、APIを使った簡単なサンプルは無いでしょうか?

よろしくお願いします。

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

Re: 簡単なサンプル

投稿記事 by eForce技術担当 » 2014年8月29日(金) 14:26

こんにちは、eForce技術担当です。
yys99 さんが書きました: アプリケーションのサンプルは読みずらいので、APIを使った簡単なサンプルは無いでしょうか?
ネットワークアプリケーションは TCP、UDP また サーバ、クライアント によりソースコードの書き方が若干異なります。
はじめに、μNet3 APIを使用した簡単なTCPサーバアプリを用意いたしました。

コード: 全て選択

// ※ "NET_C"定義は定義有りで μC3/Compact, 無しでμC3/Standard を表します。

/* エコーサーバ処理 */
ER echo_server(void)
{
    ER ercd;
    T_NODE host;
    VB ebuf[256];

#ifndef NET_C
    ID ID_TCP_ECHO;
    
    /* ソケットの生成 */
    memset(&host, 0, sizeof(host));
    host.num = 1;
    host.ver = IP_VER4;
    host.ipa = INADDR_ANY;
    host.port = 12345;
    ercd = cre_soc(IP_PROTO_TCP, &host);
    if (0 >= ercd) {
        return ercd;
    }
    ID_TCP_ECHO = ercd;
#endif

    /* クライアント接続待ち */
    memset(&host, 0, sizeof(host));
    ercd = con_soc(ID_TCP_ECHO, &host, SOC_SER);
    if (E_OK != ercd) {
        return ercd;
    }

    /* エコー動作 (受信したパケットをそのまま送信元に送信する) */
    for (;;) {
        ercd = rcv_soc(ID_TCP_ECHO, ebuf, sizeof(ebuf));
        if (0 >= ercd)  break;  /* 切断 もしくは 通信エラー発生で処理を抜ける */

        ercd = snd_soc(ID_TCP_ECHO, ebuf, ercd);
        if (0 >= ercd)  break;  /* Error */
    }

    /* 切断処理 */
    ercd = cls_soc(ID_TCP_ECHO, SOC_TCP_CLS);
    
#ifndef NET_C
    /* ソケットの削除 */
    ercd = del_soc(ID_TCP_ECHO);
#endif
    return ercd;
}

/* エコーサーバ用タスク */
void EchoServerTask(VP_INT exinf)
{
    ER ercd;
    
    do {
	    ercd = echo_server();
    } while (E_OK == ercd);
    
    /* 切断(or ソケット削除)の異常発生時処理 */
}
エコーサーバ(クライアントからサーバにデータを送信すると、そのまま返ってくる)として動作します。
TeraTerm等で該当アドレス・ポートに接続して、データを送信するとそのままの形でデータが返ってきます。

次に同様のものを、UDPソケットを使用したものが以下となります。

コード: 全て選択

// ※ "NET_C"定義は定義有りで μC3/Compact, 無しでμC3/Standard を表します。
/* エコーサーバ処理 */
ER echo_server_UDP(void)
{
    ER ercd;
    T_NODE host;
    VB ebuf[256];

#ifndef NET_C
    ID ID_UDP_ECHO;

    /* ソケットの生成 */
    memset(&host, 0, sizeof(host));
    host.num = 1;
    host.ver = IP_VER4;
    host.ipa = INADDR_ANY;
    host.port = 12345;
    ercd = cre_soc(IP_PROTO_UDP, &host);
    if (0 >= ercd) {
        return ercd;
    }
    ID_UDP_ECHO = ercd;
#else
    /* コンフィグレータでID名が ID_UDP_ECHO のソケットを作成する */
#endif

    /* クライアントからの接続待ちに con_soc() は不要 */

    /* エコー動作 (受信したパケットをそのまま送信元に送信する) */
    for (;;) {
        ercd = rcv_soc(ID_UDP_ECHO, ebuf, sizeof(ebuf));
        if (E_TMOUT == ercd)  continue;     /* タイムアウトで処理継続 */
        if (0 >= ercd)  break;              /* 通信エラー発生で処理を抜ける */

        /* 受信パケットの送信元アドレスを確認する */
        ref_soc(ID_UDP_ECHO, SOC_IP_REMOTE, (VP)&host);     /* 受信元のアドレスを取得して */
        con_soc(ID_UDP_ECHO, &host, 0);                     /* 送信先に指定する */

        ercd = snd_soc(ID_UDP_ECHO, ebuf, ercd);
        if (0 >= ercd)  break;  /* Error */
    }

    /* UDPはコネクションレスのため cls_soc() はしなくても良い (接続先情報がクリアされる) */
    ercd = cls_soc(ID_UDP_ECHO, 0);

#ifndef NET_C
    /* ソケットの削除 */
    ercd = del_soc(ID_UDP_ECHO);
#endif
    return ercd;
}


/* エコーサーバ用タスク */
void EchoServerTask(VP_INT exinf)
{
    ER ercd;

    do {
        ercd = echo_server_UDP();
    } while (E_OK == ercd);

    /* 切断(or ソケット削除)の異常発生時処理 */
}
UDPはコネクションレスの接続のため、con_soc(), cls_soc() の意味がTCPと異なります。
con_soc() を実施すると送信元アドレスを指定できます。cls_soc() を実施すると指定したアドレス情報をクリアできます。
rcv_soc() でパケットを受信した後、ref_soc(SOC_IP_REMOTEパラメータ指定)を行うことで送信元アドレスが取得できます。

返信する