前回は、うさちゃんRabbit4000とラズパイ4の間でDNSのやり取りでした。今回からはftpしてみます。うさちゃんがクライアント、ラズパイ4がサーバという役回りです。今回はうさちゃんに書き込んだftpクライアントのサンプルプログラムで、ラズパイ4上のvsftpdサーバからファイルをゲットできることを確かめるまで。
※「うさちゃんと一緒」投稿順 Index はこちら
※Rabbitシリーズのマニュアルは、販売元のDigi社のページからダウンロードできます。
※実験にはRabbit4000搭載のRCM4010モジュールを使用しています。ソフトウエアはDynamic C 10.72でコンパイルしています。
※うさちゃんに対向するFTPサーバには、Raspberry Pi 4 model B(Raspberry Pi OS 64bit bullseye)にインストールしたvsftpdを使用しています。
ftpクライアントのサンプルプログラム
Dynamic C処理系には、多くのサンプルプログラムが付属しており、今回はftpクライアントということで、以下のソースを選択いたしました。
Samples\tcpip\ftp\FTP_CLIENT.C
上記に、当方ネットワークの諸元を書き込んでとりあえず動かしてみたところが以下に(末尾にソース修正点はまとめてます。)ダメでした。
なにが悪いのか、サンプルソースをみると上記の last code = 530 で530と表示されているエラーコードは、ftp で規定されているコードだということがわかりました。サーバから返ってきているのね。サーバとの通信はできているみたいだけれども、うまく握れてない? その意味を知るには、RFCを見るしかないデス。
上記はオリジナルの英文ですが、ネットを探すと日本語訳してくださっている方も多いみたいっす。
さて530をみてみると以下のようでした。
530 Not logged in
ログインできない?ということで調べてみたら、ftpのユーザ名がエラーでした。なんのことはない?
ftp通信はできてるみたいだけれども
ftpのユーザ名を修正したところ、以下のようにOKとなりました。ファイルをダウンロードできてるみたい。
でもね、上記ではファイルのサイズ(8バイト)のみ表示して内容は不明です。いつものようにwiresharkでパケットを確認する手もありますが、とりあえず、ウサちゃん側に届いたファイルの内容を表示してもらいたい。
そこで受け取ったファイルバッファの内容をStdioにダンプするところを追加してみたのが以下に。
末尾から3行目の=> と 2行目の<== に囲まれている 「abcedfg<改行>」が受け取ったファイルの中身です。
ftpサーバとして動いているラズパイ4上でファイルの中身を見るとこんな感じ。
念のためにHEXダンプすると、8バイト目には0x0A(LF)が入っていることが確認できます。
さらに vsftpdのログを確認してみると 192.168.2.59(うさちゃんのIPアドレス)から接続され、ログインされ、ダウンロードされているのが確認できました。
動作はOKそうだね。
うさちゃん側のサンプルソースの修正点
まず、ネットワークアドレスやftpのための設定 #defineは以下のとおり。なおREMOTE_PORTが0になってますが、0だと「デフォルト・ポート」へ行くみたいです。
#define TCPCONFIG 1 #define _PRIMARY_STATIC_IP "192.168.2.59" #define _PRIMARY_NETMASK "255.255.255.0" #define MY_GATEWAY "192.168.2.1" #define MY_NAMESERVER "192.168.2.126" #define REMOTE_HOST "192.168.2.126" #define REMOTE_PORT 0 #define REMOTE_USERNAME "XXX" #define REMOTE_PASSWORD "XXX" #define REMOTE_FILE "a.txt"
後はお好みです。使用したDCのサンプルソースは、ダウンロード、アップロードを繰り返し、場合によってはftpサーバにもなるようなものなのですが、いろいろ一度にやるとわけわからなくなるので、
main()関数内でdownload_normal()以外コメントアウト
としています。これにより指定のサーバから1ファイルをダウンロードするだけとなります。後でwiresharkで観察するときに楽、というだけ。手抜きだな。
また、さきほど述べたように、ダウンロードしたファイルの中身を確認(といって大規模なファイルは想定していないデス。1バッファ限定)するのに、以下の関数に
download_normal()
以下のようなコードを加えてファイル内容(テキスト)をダンプするようにしてます。
buf[ftp_client_filesize()] = '\0'; printf("Data =>%s<==\n", buf);
まあ、これでftpできるようになったので、次回はwiresharkで観察か。