none
TCP/IPで不通になるとUDPも不通になるのか? RRS feed

  • 質問

  • 以前、下記質問をさせていただいた、無限極限です。

    その節は大変ありがとうございます。

     

    TCP/IPで通信中に突然パケット欠損・切断

    http://forums.microsoft.com/MSDN-JA/ShowPost.aspx?PostID=3200849&SiteID=7

     

    サーバとクライアントの間でTCP/IPが不通になった場合の事を考えて

    クライアント側でUDPにて受信待機させておき、TCP/IPが不通になった場合

    サーバからUDPで通信してTCP/IPを復旧するといったプログラムを組んでみました。

    自分でシュミレーションしたらうまくいった(TCP/IPは正常ですがUDPで通信して)ので、

    プログラムに問題はないのですが

    実際問題TCP/IPが不通になった後にUDPで送信してもパケットがうまく届いていないようです。

    TCP/IPがだめになるとUDPもだめなのでしょうか?ご存知の方教えて頂ければありがたいです。

    2008年5月26日 4:12

すべての返信

  • TCP/IPがだめになるとUDPもだめになるほうがむしろ普通ではないでしょうか?

    それこそ、ネットワーク接続が論理的・物理的に切れている状態でしょう。

     

    ・・・まぁ、さすがにそんなことは承知だと思いますので、そうではない何か、つまり、「TCP/IPはだめだけど、UDPはうまく届くはず」と考えている、何か理由があるのではないでしょうか?

     

    そのあたりを説明していただけますか?

    2008年5月26日 9:42
  • 西脇さんまた、相談に乗って頂きありがとうございます。

     

    UDPもだめなのは普通なのですか。これは単に僕の思慮が浅かっただけです。

    ただ、サーバとクライアントの間でこんな現象が起きました。

     

    TCP/IPが20人中3人がだめになったので(物理的にはつながってます)、こちらからUDPで通信をし

    クライアント側のソフトに組み込んである再接続処理をさせようとしましたがだめでした。

     

    が、しばらくたってからサーバ側でほぼ同時に3人分のエラーメッセージが出ました。

     

    20:57:12 転送接続からデータを読み取れません: 既存の接続はリモート ホストに強制的に切断されました。。

    20:57:12 転送接続からデータを読み取れません: 既存の接続はリモート ホストに強制的に切断されました。。

    20:57:12 転送接続からデータを読み取れません: 既存の接続はリモート ホストに強制的に切断されました。。

     

    TCP/IPのみでやってるときはこんな事は起こりませんでした。

     

    以上のようなことなのです。

    これだけでは、何とも言えないかもしれません。その時はすいません。

     

     

     

    2008年5月26日 15:29
  • System.IO.IOException: 転送接続からデータを読み取れません。

    ---> System.Net.Sockets.SocketException: 既存の接続はリモート ホストに強制的に切断されました。

     

    典型的なネットワーク障害ですね。

     

    InnerExceptionのSystem.Net.Sockets.SocketExceptionを調べると、

    SocketErrorCodeプロパティは、WSAECONNRESET (10054) になっているはずです。

     

     

    ネットワーク担当に、WSAECONNRESETが頻繁に発生するので、対応して欲しい、と言って、調べていただくと良いと思います。

    2008年5月27日 2:10
  • アドバイスありがとうございます。

     

    ちなみに、僕が作ったソフトはソフト起動時に自動的にサーバへ接続するようにしているのですが

    接続がだめになってソフトを再起動するとすんなりと普通にサーバとつながるのです。

    ついさっきまでだめだったのに、やり直すとすんなり接続できてしまうのは何ででしょうか?

     

    2008年5月27日 16:05
  • 原因をしりたいなら「接続がだめ」になったときのエラーコードをみるなり、デバッグするなりして原因を調べればよいかと。「接続がだめ」というだけでは、あまりにも原因となりうる要因が多すぎて答えられません。

     

    ネットワークを経由して通信をおこなうアプリケーションは、貴方の作ったソフトウェアだけで成り立っているわけではありません。間には多数のハードウェアやソフトウェアが介在し、それらは貴方の管理下にないのが普通です。したがって通信中にエラーが起こるのは当たり前で、アプリケーション側ではエラー時にどのようにリカバリするのかまで含めて設計するものです。

     

    「やり直す」ことはエラーリカバリの基本です。修復不可能な通信エラー(ネットワークの切断など)でない限り、大抵の場合はやり直せばうまくいきます。なぜと言うことに言及したいなら、ネットワークの本でも買ってきて、をきちんと学習すればよろしいかと思います。

    2008年5月29日 1:01
  • そうですよね。 

    接続がダメになっても、再接続をするとうまくいくのは、なぜですか?というのは、かなり難しい質問だと思います。

    分かり切ったことだとは、思いますが、ネットワーク通信は、いくつかのアプリケーション・レイヤ(層)を通ることで実現されています。
    各々のレイヤに属するモジュールは、他のレイヤとは独立して動作し、隣接するレイヤとは決まったやり取り(プロトコル)で会話します。このいくつかのレイヤは、ISOではOSI参照モデル(OSIネットワークモデル)として定義されており、送信側と受信側の両方に存在します。

    ネットワーク通信を行うには、通信相手を限定する必要があります。その限定するための住所にあたるのがIPです。
    IPは、OSI参照モデルのネットワーク層というレイヤに属するものですが、この層は、通信経路の洗濯や通信経路内の住所の管理なんかを行います。 これで通信相手は特定できますが、送ったデータをきちんと理解できるソフトウェアを限定しないといけません。 たとえば、アメリカ人と日本人、フランス人が同居した家に、あなたが、その家に住む日本人に手紙を出したとしましょう。その手紙には、住所しか書いてありません。これでも郵便はその家に届きますが、最初にその手紙を読んだのが日本語が全く読めないフランス人だったら、どうでしょう? あながた送った手紙は、フランスの人には読めませんよね? ネットワーク通信も同じです。あなたが住所を特定して送るだけでは、あなたが通信したいアプリケーションに届く保障はありません。 そこで、ポート番号を指定するのです。ポート番号は、その住所に存在するアプリケーションを選定するための名前みたいなものです。住所と名前がそろって、初めて通信が行えるのです。

    一方、TCPとUDPは、OSI参照モデルの内、トランスポート層と呼ばれているレイヤに属しているモジュールです。
    トランスポート層は、送信時にはデータを圧縮し、受信時にはデータを復元したり、誤り訂正を行ったりということを行う層です。
    TCPは、信頼性が高い代わりに転送速度は低く、UDPは、転送速度は高いのですが、信頼性は低いといった特徴があります。

    OSI参照モデルには7つの層が定義されており、それぞれの層で何を行わないといけないのかという債務が規定されています。先にあげたのは、その中の2つだけです。他のレイヤにもそれぞれ役目があり、そこで動作するモジュールが稼働している必要があります。

    簡単に説明しましたが、このように色々なレイヤを通ることでネットワーク通信は、行われるため、接続が切れる原因は随所にあります。たとえば、通信相手のアプリケーションがビジー状態で応答できなくても、切断されますし、通信相手のアプリケーションがダウンしても切断されます。ファイアオールに蹴られても通信はできませんよね。他にも色々と接続がきれる原因は存在します。 

    ですので、もう一度、落ち着いて、何が原因なのかを探ってみてください。
    もし、エラー内容を見てもわからないようであれば、菱星さんのおっしゃるように、書籍などを読むことをお勧めします。
    ネットワーク通信は、奥が深いので、頑張ってみてください。

    長々と、分かり切ったこと&偉そうなことを言いましたが、お気を悪くしないでください。 

    2008年5月29日 2:39
  • 「ついさっきまでだめだったのに、やり直すとすんなり接続できてしまう」のは、私の経験でもあります。

    以前のメッセージを引用します。

     

     西脇 さんからの引用

    無限極限さんのいうような事例が、私の経験でもあります。

     

    とある端末~センター間の通信をTCP/IPで行っているシステムでの例です。

     

    全試行回数:22156回

    問題発生数:10回

     

    発生率にすると0.0451%です。

     

     

    データ受信のタイミングでエラー発生、60秒待って受信リトライしてもダメでした。

    接続をいったん切り、接続からやり直すと正常にTCP/IP通信ができます。

     

    なので、接続からやり直すようにリトライする仕組みを導入、問題が表面化しないようにしました。

    このような方法なら、無限極限さんの手の届く範囲のことで対処しようがあると思いますがいかがでしょうか?

     

    「何ででしょうか?」に関しては、無限極限さんの作ったソフトが動作するネットワークを調査しなければわかるはずもありません。

    ネットワーク担当に調べてもらうと良いと思います。

     

     

    上記の私の経験。私はネットワーク担当に調べてもらいました。

     

    でも「この確率(0.0451%)でのネットワーク障害発生は仕方ない」という回答。

    しかし、数百台のデータ受信アプリケーションレベルでそれ以上の信頼性が必要であったため、対策を行うに至りました。

     

    私が行った対策も「ソフトを再起動」。

    結果も同じ「するとすんなりと普通にサーバとつながる」でした。

     

     

    そのシステムの実例数値。

     

    全試行回数:32978回

    問題発生数:16回

     

    端末側の通信部分は他社製であったため、ソフトを再起動する仕組みを導入しました。

    1ヶ月以上経過しましたが、1度も問題が表面化していません。

    2008年5月29日 5:41
  • みなさん、ご返信ありがとうございます。勉強してみます。

     

    ちなみになぜTCP/IPは接続しなおすとすんなりうまくいくかという質問をしたのは

    UDPの場合、とくに接続を確立するといった操作がないので

    サーバからクライアントへ送信したとき、毎度毎度通信経路を

    切り開いて送信しているのではないかと思ったからです。

     

    TCP/IPが接続し直すとうまくいくように、UDPは送信ごとに通信経路を

    確立してくれているのではないかと、不勉強のため勝手に予測してしまいました。

     

    それと、今回の件については自宅のパソコンでやっていることでして

    普通にプロバイダと契約してる回線なのでネットワーク担当という人は

    プロバイダの人ということになるのでしょうか?

    そうであれば聞いてみます。プロバイダが対応してくれるか不明ですが・・・。

     

     

    2008年5月29日 16:35
  • えーと、上でも書きましたが、IPはネットワーク層に所属します。
    上では、簡単にIPは相手先の所在(住所)を示しますと書きましたが、
    正確には、IPはプロトコルです。IPというプロトコルは、一方通行のデータ送信を実現しているだけです。
    IPというプロトコルが扱うのがIPアドレスつまり、通信相手(ホスト)の住所です。

    ホストが分かるだけでは、通信はできませんので、ホスト上のアプリケーションを特定する必要があります。
    これも上記に書いたとおりです。このアプリケーション同士を結び付けるのは、IPプロトコルではなく、
    TCPやUDPの役割です。

    つまり、TCPもUDPもIPプロトコルを使って、接続を確立します。
    接続を確立しなければ、ネットワークは接続できません。

    無限極限さんが、どのクラスを使ってネットワーク接続を実装しているのかが不明ですが、
    TcpClinet、TcpListner、およびUdpClientを使っているのであれば、これらは、Socketクラスの上位に
    位置しており、ある程度の制御は各クラス内で行っています。 つまり、詳細な制御が隠れてしまうのですよ。
    一方、Socketクラスは、TcpClientなどに比べると、低級なクラスですが、その代り、多くのことを自分で制御できます。

    何が言いたいかというと、これらのクラス群の内、どれを使うにしても、ネットワークの知識はある程度必要になるかと思います。
    「Visual C#.netで始めるTCPネットワークプログラミング」なんて、値段も安く、とっつきやすい書籍もありますので、一度、基礎固めをなさった方が宜しいかと思います。

    ところで、無限極限さんは、プロバイダが公開しているWebサーバやメールサーバとやり取りしているのでしょうか??
    てっきり、LAN内でサーバとクライアントを作成しているのだと思ってたのですが、違うのですか???
    それとも、インターネット越しに遠隔地のホストとやり取りをしている???? そのへんが今一つ分からなくなってきたのですが…。

    尚、普通に個人契約しているようなプロバイダとの関係ですと、おそらく無限極限さんの内容には対応してもらえないかと…。

    2008年5月30日 2:48
  • まずは、発生した例外(Exception)を皆さんに見ていただいてはどうでしょうか?
    発生したExceptionのToString()メソッドを実行すると、発生した例外クラス、メッセージ、内部例外、スタックトレースなどが、文字列として返ります。

     

    .NET Framework クラス ライブラリ
    Exception.ToString メソッド

    http://msdn.microsoft.com/ja-jp/library/system.exception.tostring(VS.80).aspx

     

    これらは、状況を把握する上で有用な情報ですので、省略せずにそのまま書き込んで見て下さい。

    2008年6月4日 7:37
  • みなさん、アドバイスありがとうございます。

     

    あれから、色々と接続が途絶えてしまう人の環境を調査してみたところ

    TCP/IPがだめになってしまう人はルータを使っており、さらにしばらく無通信状態が続いた後に

    発生してました。

     

    自分なりに検索してみたところルータには無通信監視タイマという機能がついているようで

    これが作動した結果なのかとも思いましたがルータが接続を切断したのであれば

    サーバに直ちに反応が返ってきてもよさそうなものなのですがサーバにレスポンスは

    ありません。

     

    以上、追記でした。

     

     

    2008年6月16日 9:52
  • こんにちは。中川俊輔 です。

     

    皆様、回答ありがとうございます。

     

    無限極限さん、フォーラムのご利用ありがとうございます。

    勝手ながら有用な情報と思われる回答へ回答済みチェックをつけさせていただきました。

     

    回答済みチェックが付くことにより、有用な情報を探している方が情報を見つけやすくなります。
    有用な情報と思われる回答があった場合は、なるべく回答済みボタンを押してチェックを付けてください。

    無限極限さんはチェックを解除することもできますので、ご確認ください。

     

    それでは!

    2008年7月4日 7:37