Java で bitTorrent クライアントを開発しています。オンラインにはたくさんのライブラリがあることは知っていますが、どうしようもありません。私は自分のものをしたい。とにかく、私はいくつかの奇妙な振る舞いに気付きました。
- 接続しようとしているすべてのピアの約 80% で、接続が失敗します (
socketTimeOut
または「接続できません」エラー)。明らかに、ピアのリストはトラッカーから受信されます。また、いくつかの IP をランダムに ping してテストしました。通常、ping は成功します。 - 接続するとき:
- HandShake 後の 50% ドロップ接続、
- 30% で奇妙な動作に気付きました: ハンドシェイクを受信し、BitField を受信し (すべてのピースを持っています)、+20 の Have メッセージで攻撃され (BitField で既に言及されているピースのインデックスを確認しました)、接続を切断します。 、これは奇妙です。
(すべての統計について、数字は正確ではありません。)
BitTorrent に関するいくつかの質問:
更新#4:回答が見つかったことを考慮して、いくつかの質問を切り捨てています
これは「接続失敗率 80% の質問」です。
80% の接続失敗率の原因は何ですか? 私が接続しようとしたすべてのクライアントが私のための余地がなかったという意味で、これは不運ではありません. 私は 6881 でリッスンしていますが、他のポートでもテストされています。昨日、私は大成功を収めました。多数の接続が受け入れられました (同じコード、先週のいくつかの変更)。Piece メッセージが流れ始めました..だから、私のコードは完全に役に立たないわけではありません。トレントクライアントは、トラッカーを閉じる前に最後のメッセージを送信して
event=stopped
、ピア情報で内部データベースを更新し、応答として役に立たないピア情報を含むリストを送信しないようにしますか? または、彼らはそうすべきです.. 本当に私は死んだ仲間を受け取っているようです.- 受信したピアの順序は重要ですか? たぶん、完了のパーセンテージ..または本当にランダムです。
- また、時々、ポート 0 のピアを受信すると、Socket コンストラクターが例外をスローします。ポート 0 とは何ですか? どのポートでも接続できますか?
- 通信しようとしている torrent クライアントが開始された接続を継続するかどうかに影響を与えることができますか? ID として「-AZ2060-」を使用して Azureus クライアントであると嘘をついたらどうなりますか?
- これは「ピアを怖がらせる作品の入手可能性の問題」でした。
私の作品の入手可能性は仲間を怖がらせますか? 接続しようとしていて、空のビットフィールドを送信しました (ピースがありません[length: 1][Id = 5][payload: {}]
)。彼らはビットフィールドを送信しているようです、私はビットフィールドを送信しています..(クレイジーなメッセージを送信する人もいます)、彼らは私が貧しいことに気づき、私を落とします..ハンドシェイク後に接続を切断する人もいます。(失礼ですね。) - 従来のポート間隔 (6881 ~ 6889) を使用しない利点はありますか?
- これは「悪い仲間の質問のリスト」でした:
torrent クライアントは内部的に悪いピアのリスト (ブラック リストなど) を保持していますか? 素敵なピアを見つけた後、テストでその情報を継続的に使用しましたが、1/3 の接続しか受け入れられませんでした。接続が再び成功するまでに 10 分かかることもありました。
更新 #1: μTorrent クライアントとの接続は、前述のパターン (BITFIELD、HAVE 砲撃、クローズ接続) で動作するようです。多数の bitTorrent クライアント (μTorrent、BitTorrent、Vuze、BitCommet、Deluge) を使用してローカルでテストしたところ、μTorrent でのみこのパターンに気づきました。他のものでは、コミュニケーションは問題ありませんでした (HS、BITFIELD、UNCHOCE、幸せなピースの共有)。さて、この μTorrent はおそらく最も人気のある bitTorrent クライアントです (6/8 接続が開始されたのは μTorrent でした)。
更新 #2: a を維持するという点では、"bad list,"
そう思われます (そして、実際にそうすることは理にかなっています)。たとえば、μTorrent では、次のような接続なし間隔 (30 秒、1 分、1 分 30 秒、2 分..) があることに気付きました。「接続なし」とは、前の接続が終了した後、x
数秒間新しい接続が受け入れられなかったことを意味します。
更新 #3: HAVE メッセージ砲撃は、いわゆる「レイジー ビットフィールド」であった可能性があります (いくつかのテストを行ったところ、HAVE で言及されている各部分は BITFIELD には存在しませんでした)。μTorrent と BitTorrent がこのアプローチを使用していることがわかります。
別の結論: 一部のクライアントは、BitTorrent 仕様を尊重するという点でより制限的であり、ルールを破ると接続を閉じます. 例: BitTorrent と BitTornado で、ビットフィールド メッセージを送信してもピースがない場合、接続が閉じられることに気付きました (ピースがない = 空のビットフィールド.. しかし、仕様では「オプションであり、クライアントにピースがない場合は送信する必要はありません」 ")、一方、UNCHOKE メッセージを送信する前に何らかのタイプのメッセージを送信すると、他のユーザーは接続を閉じます (INTERESTED でさえありません)。
更新 #4: 私は主に最初の質問に関心があるので (私の 80% の接続失敗率の理由は何でしょうか?.. ストライクされた質問はおそらく好まれています)、接続が失敗することがある理由のいくつかの説明を以下に示します。
1)前の接続を停止した直後にピアとの接続を開始した場合(停止-ソケットを閉じることを意味します):反対側のピアは次の読み取り/書き込みまで認識しません。
詳細: - これは何度も気付きました。これは、ダウンロードが完了した後でより明白になります。接続を閉じると、ピアは新しい KEEP_ALIVE を送信しようとするまで (~2 分)、これを認識しません。しかし、交換REQUEST-PIECE中に閉じると、ピアはかなり速く認識します..接続を閉じた後の最初のシナリオでは、uTorrentピアタブにまだ存在しています. ロガー タブの中を見ると、約 2 分後に、私がいなくなったことに気付きます。
2) uTorrent は、私の BITFIELD メッセージが破損していることを認識しているようです (& 明らかに、受信後に接続を閉じる必要があります) (これは常に発生するとは限りません.. また、確認して再確認しました。メッセージは問題ありません & 他の BT クライアントではそのような問題はありませんでした) .
詳細: - uTorrent ロガー タブの中を見ると、ビットフィールドを送信した直後に「切断されました: 不正なパケット」と表示されます - 遅延ビットフィールドの実装を試す予定です。クライアントはこれを行います)
3)(おそらく#1にリンクされている以上)uTorrentが再接続を許可しない場合、ロガータブに次のように表示されます:「切断:すでに同等の接続があります(余分な接続がドロップされました)」..現在、ランダムなローカルポートを選択しています新しい接続を開始するとき (大部分の BT クライアントでこれが実装されているのを見ました)、これはそれをだましません。彼はまだ自分の「ピア リスト」にピアが既に存在していることを確認します (おそらく IP は一致します)。テストの 30% で、同じシナリオで、再接続できます :) .. 理由はまだわかりません
4)もう1つ:uTorrentでトレントを閉じた後も、「着信接続のリスナー」はまだ生きているようです(閉じるとは、右クリック+停止を意味します)。これは、まだ接続を開始して HANDSHAKE を送信できることを意味します。この後、切断されます (ハンドシェイクは返されません)。uTorrentロガーのメッセージ:「切断:トレントはありません:80FF40A75A3B907C0869B798781D97938CE146AE」、この長い文字列は私の情報ハッシュです..他のBTクライアントでもテスト中にこれを見ました.
いくつかの詳細情報:
- タイプフルアップロード/部分アップロードおよびフルダウンロードのuTorrentを使用したシナリオは成功しますが、部分ダウンロードのシナリオはそれほど多くありません..おそらく#2が原因です
- 私はまだuTorrentでbitField +砲撃+接続を閉じていることを取得しています..ロガータブで同じメッセージを覚えているので、「切断:不良パケット」..おそらく#2が原因です
- uTorrent のほかに、BitTorrent、BitTornado、BitCommet、qBitTorrent、FlashGet (通信は問題ありませんでした) と Vuze、FrostWire、Shareaza (これらの連中は問題なく動作しました) でテストしました。
- すべてのクライアントが同じように動作するわけではありません。例: FlashGet と uTorrent (および BitCommet?) は、INTERESTED を送信するまでチョークを解除しません.. 他の人は、BITFIELD の直後にチョークを解除するようです.. この意味で、クライアントを別の方法で扱うことを計画しています (これは本当に必要だと思います)。 ..おそらくビットフィールドから名前を推測し(命名規則は2つしかありません)、そこから始めます..すでに何かを実装しています。これが、uTorrentタイプのクライアントに接続したことを知る方法です..