13

質問が関係ない場合は、これを移動/閉じてください。

コア: Cortex-M4

マイクロプロセッサー: TI TM4C1294NCPDT。

IP スタック: lwIP 1.4.1

私はこのマイクロプロセッサを使用してデータのロギングを行っており、次の形式の HTTP リクエストを介して別の Web サーバーに情報を送信したいと考えています。

http://123.456.789.012:8800/process.php?data1=foo&data2=bar&time=1234568789

プロセッサが応答ヘッダーを確認できるようにしたい (つまり、200 OK だった場合や何か問題が発生した場合) - 実際のコンテンツを表示/受信する必要はありません。

lwIP にはマイクロプロセッサ用の http サーバーがありますが、私は反対です (マイクロプロセッサがクライアントです)。

パケットが要求/応答ヘッダーにどのように関連付けられているかがわからないため、実際に情報を送受信する方法がわかりません。

4

2 に答える 2

22

これは実装が非常に簡単になり、この質問を更新するのを忘れました。

Raw/TCP の「ドキュメント」であるこのサイトに記載されている指示にほとんど従いました。

基本的に、HTTP リクエストは TCP パケットでエンコードされるため、PHP サーバーにデータを送信するために、TCP パケットを使用して HTTP リクエストを送信しました (lwIP がすべての作業を行います)。

送信したい HTTP パケットは次のようになります。

HEAD /process.php?data1=12&data2=5 HTTP/1.0

ホスト: mywebsite.com

これを HTTP サーバーが理解できるテキストに「翻訳」するには、コードに「\r\n」キャリッジ リターン/改行を追加する必要があります。したがって、次のようになります。

char *string = "HEAD /process.php?data1=12&data2=5 HTTP/1.0\r\nHost: mywebsite.com\r\n\r\n ";

末尾に「\r\n」が 2 つあることに注意してください。

GET または HEAD を使用できますが、私は PHP サーバーが返す HTML サイトを気にしなかったので、HEAD を使用しました (成功すると 200 OK を返し、失敗すると別のコードを返します)。

lwIP raw/tcp はコールバックで機能します。基本的にすべてのコールバック関数を設定し、必要なデータを TCP バッファ (この場合は上記で指定した TCP 文字列) にプッシュし、lwIP にパケットを送信するように指示します。

TCP 接続をセットアップする関数 (この関数は、TCP パケットを送信するたびにアプリケーションによって直接呼び出されます):

void tcp_setup(void)
{
    uint32_t data = 0xdeadbeef;

    /* create an ip */
    struct ip_addr ip;
    IP4_ADDR(&ip, 110,777,888,999);    //IP of my PHP server

    /* create the control block */
    testpcb = tcp_new();    //testpcb is a global struct tcp_pcb
                            // as defined by lwIP


    /* dummy data to pass to callbacks*/

    tcp_arg(testpcb, &data);

    /* register callbacks with the pcb */

    tcp_err(testpcb, tcpErrorHandler);
    tcp_recv(testpcb, tcpRecvCallback);
    tcp_sent(testpcb, tcpSendCallback);

    /* now connect */
    tcp_connect(testpcb, &ip, 80, connectCallback);

}

PHP サーバーへの接続が確立されると、「connectCallback」関数が lwIP によって呼び出されます。

/* connection established callback, err is unused and only return 0 */
err_t connectCallback(void *arg, struct tcp_pcb *tpcb, err_t err)
{
    UARTprintf("Connection Established.\n");
    UARTprintf("Now sending a packet\n");
    tcp_send_packet();
    return 0;
}

この関数は、次のように、HTTP 要求を送信する実際の関数 tcp_send_packet() を呼び出します。

uint32_t tcp_send_packet(void)
{
    char *string = "HEAD /process.php?data1=12&data2=5 HTTP/1.0\r\nHost: mywebsite.com\r\n\r\n ";
    uint32_t len = strlen(string);

    /* push to buffer */
        error = tcp_write(testpcb, string, strlen(string), TCP_WRITE_FLAG_COPY);

    if (error) {
        UARTprintf("ERROR: Code: %d (tcp_send_packet :: tcp_write)\n", error);
        return 1;
    }

    /* now send */
    error = tcp_output(testpcb);
    if (error) {
        UARTprintf("ERROR: Code: %d (tcp_send_packet :: tcp_output)\n", error);
        return 1;
    }
    return 0;
}

TCP パケットが送信されると (データが実際に送信されたかどうかを気にせず、「最善を期待」したい場合はこれで十分です)、PHP サーバーは TCP パケットを返します (200 OK など)。 HEAD の代わりに GET を使用した場合は HTML コード)。このコードは、次のコードで読み取って確認できます。

err_t tcpRecvCallback(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
    UARTprintf("Data recieved.\n");
    if (p == NULL) {
        UARTprintf("The remote host closed the connection.\n");
        UARTprintf("Now I'm closing the connection.\n");
        tcp_close_con();
        return ERR_ABRT;
    } else {
        UARTprintf("Number of pbufs %d\n", pbuf_clen(p));
        UARTprintf("Contents of pbuf %s\n", (char *)p->payload);
    }

    return 0;
}

p->ペイロードには、実際の「200 OK」などの情報が含まれています。うまくいけば、これは誰かを助けます。

答えを簡単にするために、上記のコードでいくつかのエラー チェックを省略しました。

于 2015-01-23T08:35:54.350 に答える
1

ウィキペディアのHTTP の例を見てください。クライアントは GET 行と HOST 行を送信します。サーバーは、応答のために多くの行で応答します。最初の行には応答コードがあります。

于 2014-10-06T18:46:14.927 に答える