質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

Q&A

解決済

1回答

1943閲覧

FTPからファイル一覧を完全に取り切りたい

kanbye

総合スコア17

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

0グッド

0クリップ

投稿2016/10/24 06:26

FTPサーバーのファイル一覧を取得する関数を作成しています。が、長い一覧になると、途中までしか取得できない現象が発生します。一覧の数によらず、完全に一覧を取得したいのですが、ある長さ以上になると、どうしても最後まで取得できなくなります。
なお、サーバーはサーバーOSでないWindowsのIISを利用していますが、コマンドラインの利用では最後までしっかりファイル一覧はログ出力します。
ファイル一覧の取得はWinsockではFtpFindFirstFile/InternetFindNextFileで取得可能ですが、最終的にWinsockを利用しないため、この関数は利用できません。

取得している関数は下記のような関数です。

// LISTコマンドの結果をファイルftplist.txtに保存
void FtpList(SOCKET s) {
char buf[1024];
char szStrRcv[256] ;

FILE* fp; if (_tfopen_s(&fp, _TEXT("ftplist.txt"), _TEXT("wb+"))) { _tprintf(TEXT("ファイルが開けません\n")); return; } int len; int ncnt = 0 ; do { memset(buf,0,sizeof(buf)) ; len = recv(s, buf, sizeof(buf)-1, 0); fwrite(buf, sizeof(char), len, fp); } while (len == sizeof(buf)-1 ); fclose(fp);

}

この関数ではデータコネクションを引数として渡しています。また、この関数の前に"LIST"コマンドを実行してあります。FTPへの接続はPASV接続です。
「while (len == sizeof(buf)-1 );」を「while (len > 0 ); 」にすると、3回目までは何とか読みます(ただし、bufに満たない途中までしか読み取れらない)が、4回目で待機状態で止まります。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

lang

1do { 2 memset(buf,0,sizeof(buf)) ; 3 len = recv(s, buf, sizeof(buf)-1, 0); 4 fwrite(buf, sizeof(char), len, fp); 5} while (len == sizeof(buf)-1 ); 6

recv()の説明によると

Return value

If no error occurs, recv returns the number of bytes received and the buffer pointed to by the buf parameter will contain this data received. If the connection has been gracefully closed, the return value is zero.

なので、読み取りが成功した場合でも、引数に指定したsizeof(buf)-1より小さい値が返るかもしれません。

  • 正 - 読み取り成功。まだ続きがあるかも。
  • 0 - ブロッキングソケットの場合、接続が閉じられた。ノンブロッキングソケットの場合、もう読むものがない。
  • 負 - 失敗。

これらの場合に応じて処理をする必要があります。

さらに、ブロッキングソケットの場合 (これが初期設定です)、「もう読むものがない」ということを知る方法がないことがわかりますね。読み込む長さがあらかじめわかっていないと、いつ読み取りをやめていいかわかりません。

ノンブロッキングソケットを使うと、0が返ると「もう読むものがない」とわかります。また上記ドキュメントには、ソケットにデータが到着したかどうかは「select, WSAAsyncSelect, or WSAEventSelect」で知れると書いてあります。このあたりのコード例はネット検索でもみつかると思いますが、わからなければ追加質問してください。

投稿2016/10/24 08:33

ikedas

総合スコア4317

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問