問題タブ [networkstream]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
3 に答える
11094 参照

c# - ネットワーク ストリームがデータを読み取るのをどのように待ちますか?

私のアプリケーションには、3 つの異なることを担当するワーカー スレッドがあります。ジョブのうちの 2 つのリクエストは、私が作成したキューに表示されます。もう 1 つのジョブは、ネットワーク ストリームでリクエストが表示されるとアクティブ化されます。実行する作業がない場合、ワーカー スレッドを待機させたいと思います。2 つのキューでは、アイテムがあるときに設定される ManualResetEvent が公開されるため、これは簡単ですが、NetworkStream にはこれがないようです。NetworkStream が TcpClient から取得されました。

私が求めているのは、次のようなコードです。

NetworkStream にデータがあるときに設定される WaitHandle を取得する方法を知っている人はいますか?

0 投票する
9 に答える
67130 参照

c# - TcpClient接続が閉じているかどうかを確認するには?

私は TcpClient をいじっていて、接続が切断されたときに Connected プロパティを false にする方法を見つけようとしています。

やってみた

ただし、TcpClient が切断されている場合は表示されません。TcpClient を使用してこれを行うにはどうすればよいでしょうか。

0 投票する
3 に答える
5602 参照

.net - StreamWriter が NetworkStream にフラッシュされない

a を使用して aStreamWriterに書き込み、NetworkStreamaを使用しStreamReaderて応答を読み取ります。アプリはニュース サーバーにコマンドを送信し、応答を読み取ります。

簡略化されたコード (エラー処理などを除く):

コードは最後の行でブロックされ、おそらくネットワーク ストリームが応答を送信するのを待っています。

を使用してタイムアウト ループを設定することでアプリのハングを回避できますserverReader.Peek()が、常にタイムアウトします。私は決して応答を得ません。

サーバーとポートに telnet で直接接続してコマンドを入力すると、すぐに応答が返ってきます。

serverWriter.Flush()プロパティを使用する代わりに明示的に呼び出すとAutoFlush、ブロックされて応答が返されません。

このアプローチを使用してサーバーへの応答が得られない理由はありますか?

ありがとう!

解決済み:

上記のコード私にとってはうまくいくので、戻ってそのコードに基づいて、機能しないコードを構築しました。

ハングするコードでは、まだ serverReader.Peek() でタイムアウト ループを使用していました。Peek() は、バッファに読み取るデータがあっても、常に -1 を返します!! Peek() ループを ReadLine() へのブロッキング呼び出しに置き換えると、問題が解決します。

アプリがマルチスレッドであり、ブロックしたくないため、タイムアウトループを最初に入れました。この問題を再検討し、Peek() を使用せずにスレッドのタイミングを解決する方法を確認する必要があります。

みんなありがとう、良い答え!

0 投票する
1 に答える
2873 参照

c# - NetworkStream.CanRead は true を返しますが、バッファは値を返しません

オブジェクトからバッファーを読み取る do while ループがあります。whileNetworkStream条件はnetworkStream.CanRead、読み取り可能な限り、バッファーからの読み取りを続行する必要があります。唯一の問題は、バッファから読み取って文字列に変換するときに何もないことです。つまり、空です。

なぜそれが起こるのでしょうか?

これは ASP.NET(VS2005) アプリケーションです

@dtb コード情報:

私はNetworkStreamオブジェクトを渡していますnetworkStream

面白いことに、再接続して再度接続すると、送信/読み取りは正常に機能します。実際にSend(ここでは例外はありません)またはNetworkStreamオブジェクトの再利用に問題がありますか。これはテストTCPサーバーでローカルに正常に動作していますが、本番環境(Windows Server 2003)で上記の問題が発生しています(つまり、ストリームから何も読み取れません-実際にタイムアウトするまで(ループを終了するまで) 10秒)

0 投票する
3 に答える
27677 参照

c# - TCP接続を閉じる正しい方法は何ですか

基盤となるNetworkStream.Write()を使用して、サーバーにデータを送信するTcpClientオブジェクトがあります。そのため、私は持っています:

これで、ボタンを押すと接続が閉じます。接続を閉じる正しい方法は何ですか?MSDNのドキュメントによると、TcpClientを(.Close()を使用して)閉じると、実際にはソケットは閉じられず、TcpClientリソースのみが閉じられます(少なくとも私がドキュメントを理解した方法です)。

では、次のコードを実行すると、接続が正しく閉じられますか?

これで十分ですか、それとも最初に(何らかの方法で)ストリーム(またはサーバー)を閉じることができるかどうかを確認する必要があります(接続が半分開いている場合など)...

さらに、NetworkStream.Close()MSDNのドキュメントには、リソース(ソケットも含む)が解放されると記載されているため、ストリームを閉じるだけで十分であり、それ以降はTcpClientを使用できなくなります。

正しいアプローチは何ですか?

0 投票する
2 に答える
10039 参照

sockets - NetworkStreamクラスの使用中にクライアントのTCP切断を検出する

私の友人が問題を抱えて私に来ました。接続のサーバー側でNetworkStreamクラスを使用しているときに、クライアントが切断すると、NetworkStreamはそれを検出できません。

分解すると、彼のC#コードは次のようになりました。

クライアントが正常に接続でき、サーバーが送信されたデータを読み取ることができるという点で、コードは機能します。ただし、リモートクライアントがtcpClient.Close()を呼び出す場合、サーバーは切断を検出しません。client.Connectedはtrueのままであり、ns.DataAvailableはfalseです。

Stack Overflowを検索すると答えが得られました。Socket.Receiveが呼び出されていないため、ソケットは切断を検出していません。けっこうだ。これを回避できます。

(簡潔にするために、例外処理コードは省略しました。)

このコードは機能しますが、私はこのソリューションを「エレガント」とは呼びません。私が知っている問題に対する他の洗練された解決策は、TcpClientごとにスレッドを生成し、BinaryFormatter.Deserialize(nee NetworkStream.Read)呼び出しをブロックに許可することです。これにより、切断が正しく検出されます。ただし、これには、クライアントごとにスレッドを作成および維持するオーバーヘッドがあります。

元のコードの明快さを維持する秘密の素晴らしい答えが欠けているように感じますが、非同期読み取りを実行するために追加のスレッドを使用することは避けてください。ただし、おそらく、NetworkStreamクラスはこの種の使用法のために設計されたことはありません。誰かが光を当てることができますか?

更新: .NET FrameworkにNetworkStreamのこの使用(つまり、ポーリングブロッキングの回避)をカバーするソリューションがあるかどうかを確認することに関心があることを明確にしたいだけです-明らかにそれは可能です。NetworkStreamは、機能を提供するサポートクラスに簡単にラップできます。フレームワークでは、NetworkStream.Readでのブロックを回避するためにスレッドを使用する必要があるか、ソケット自体を覗いて切断をチェックする必要があるのは奇妙に思えました。これはバグのようです。または、機能が不足している可能性があります。;)

0 投票する
2 に答える
1851 参照

.net - NetworkStream.Read 遅延 .Net

TcpClient から継承するクラスがあります。そのクラスには、応答を処理するメソッドがあります。そのメソッドで、MyBase.GetStream を使用して NetworkStream を取得し、Read を呼び出します。

ブロックを読み取るための最初の呼び出しが長すぎることを除いて、これは正常に機能します。そして、長すぎるということは、ソケットが大量のデータを受信したにもかかわらず、任意の制限に達するまでそれを読み取らないことを意味します。パケット スニファ WireShark を使用して、大量のデータを受信したことがわかります。

受信バッファーを少量に設定しましたが、非常に少量 (ほんの数バイトなど) は役に立ちません。read メソッドに渡すバッファ バイト配列でも同じことを行いましたが、それでも遅延が発生します。

または別の言い方をすれば。私は600kをダウンロードしています。ダウンロードには 5 秒かかります (サーバーへの接続が 100k/秒を少し超える場合、これは理にかなっています)。最初の Read 呼び出しには 2 ~ 3 秒かかり、256 バイトしか使用できないことがわかります (256 は受信バッファーであり、読み込んだ配列のサイズです)。次に、魔法のように、残りの数十万バイトは、わずか数プロセスティックで 256 バイトのチャンクとして読み取ることができます。パケット スニファを使用すると、最初の 2 ~ 3 秒間に、ソケットが 256 バイトをはるかに超える量を受信したことがわかりました。私の接続は、3 秒間は 0.25k/秒ではなく、2 秒間は 400k ではありませんでした。

入ってくるバイトをソケットから取得するにはどうすればよいですか?

0 投票する
2 に答える
4094 参照

multithreading - 読み取り時のTcpClientおよびStreamReaderブロック

これが私の状況です:

チャットサーバーに接続するためのチャットクライアントを作成しています。TcpClientを使用して接続を作成し、そこからNetworkStreamオブジェクトを取得します。StreamReaderとStreamWriterを使用して、データの読み取りと書き込みを行っています。

これが私の読み取りがどのように見えるかです:

それはうまく機能し、ダンディです。私のメインプログラムでは、このReadメソッドを継続的に呼び出してデータがあるかどうかを確認するスレッドを作成します。例を以下に示します。

これは問題なく機能します。アプリケーションをシャットダウンしたいときに問題が発生します。UIからシャットダウンコマンドを受け取り、リスニングスレッドにリスニングを停止するように指示します(つまり、この読み取り関数の呼び出しを停止します)。Joinを呼び出し、この子スレッドの実行が停止するのを待ちます。そのようです:

問題は、実行が停止しないことです。コードにステップインしましたが、Read()メソッドがブロックしているため、リスニングスレッドがブロックしています。Read()はそこに座っているだけで、戻りません。したがって、スレッドがその1ミリ秒スリープしてから中断されることはありません。

十分な時間放置すると、別のパケットを取得してスレッドをスリープ状態にする機会が得られると確信しています(アクティブなチャットルームの場合、またはサーバーからpingを取得する場合)。しかし、私はそれに依存したくありません。ユーザーがシャットダウンと言ったら、シャットダウンしたいです!!

私が見つけた代替案の1つは、NetworkStreamのDataAvailableメソッドを使用して、StreamReader.Read()を呼び出す前にチェックできるようにすることです。信頼性が低く、サーバーからパケットを読み取るときにデータが失われたため、これは機能しませんでした。(そのため、正しくログインできなかったなど)

このスレッドを正常にシャットダウンする方法についてのアイデアはありますか?リスニングスレッドでAbort()を呼び出すのは嫌です...

0 投票する
1 に答える
6280 参照

c# - リモートホストが接続を閉じたことを示す NetworkStream.Read の代替?

クラスを使用した TCP/IP 接続の処理に関して、メソッドが 0 を返すのをTcpClient待つ以外に、リモート ホストが接続を閉じたかどうかをチェックする代替手段はありますか?NetworkStream.Read

0 投票する
2 に答える
6009 参照

.net - ネットワーク経由でTCPlistener/networkstreamvb.netに送信されるデータの長さを取得します

それは最も明白なことのようですが、TCPClientとTCPListenerを使用してネットワーク経由で送信されるバイトの長さを取得する方法を理解することはできませんか?これはこれまでの私のコードです:

データを読み込むバイト配列のサイズを設定するには、ネットワークストリームの長さを取得する必要があります。ただし、networkStream.lengthはサポートされておらず、機能せず、サポートされていない例外をスローします。

私が考えることができる他の唯一の方法は、データを送信する前にデータのサイズを送信することですが、これは長い道のりのようです。