1

私はC#でTcpクライアントを開発していて、TcpClientクラスを使用しています。サーバーに接続できません。

Connectアプリケーションをデバッグすると、への呼び出しが成功したことがわかりますが、これを行った後netstat、サーバーとクライアントの両方の接続のステータスを確認します。その結果、サーバーは接続ESTABLISHEDされていますが、クライアントではnetstatの結果にサーバーへの接続が表示されません。

インスタンスを読み取るTcpClientと、プロパティConnectedがtrueであることがわかりますので、問題はないはずですが、インスタンスから読み取ろうとするNetworkStreamとハングします。

ハングするとは、サーバーがデータを送信しているのに、readlineがデータをまったく取得していないことを意味します。

何が問題であり、いくつかの回避策があるか知っていますか?

ありがとう

4

4 に答える 4

2

まず、推奨事項:私の経験では、TcpClientは非同期で使用するのが最適です。

ただし、TcpClientを使用するすべての方法で、最初に要求を使用して書き込みを行わずに応答を読み取ることはできませんでした。送信していないリクエストへの応答を同期的に待機しようとすると、永久にブロックされます。

これを拡張すると、リクエストの送信は次のように行われます。

TcpClient.GetStream().BeginWrite( tcpMessage, ... );

これは、tcpMessageにある要求を送信します。これは、次のような文字列から生成されたバイトストリームになります。

byte[] tcpMessage = httpEncoding.GetBytes( httpMessage );

次のようなリクエストメッセージがあります。

httpMessage = "GET / HTTP/1.1\r\n" + ...;

これによりリクエストが送信され、サーバーは次のように収集できるレスポンスを生成します。

TcpClient.GetStream().BeginRead( ... );

そして、あなたはついに何かを受け取ることができるはずです!「あなたのリクエストが気に入らなかった!」だけでも。応答。8 D

于 2010-06-24T14:00:22.670 に答える
1

サーバーによって異なりますが、ほとんどのTCPサーバーは、クライアントが要求を送信するのを待ってから、応答を送信します。スレッドがデータを待機しているようです。読み取りタイムアウトを設定しましたか?

サーバーが応答を送信することを認識できるように、必ず要求を送信してください。

通常、TcpClientを別のスレッドに配置し、読み取りタイムアウトを使用して、プログラム全体が応答を待機するのを回避します。

ブロッキング(同期)サーバーと通信するときは、非ブロッキング(非同期)ソケットを使用しないでください。問題が発生するだけです。ほとんどのWebサービスは要求/応答パラダイムを使用するため、ソケットのブロックはWebでは正常です。

于 2010-06-24T13:27:06.370 に答える
1

あなたが見たものは絶対に正常です。

Reading the TcpClient instance I can see that the property Connected is true so it should be fine but when I try to read from the NetworkStream it hangs.

読み込もうとすると、サーバーからデータが送信されるまでスレッドがブロックされます。そうしないと、使用した読み取り方法に基づいて、永久にブロックされる可能性があります。

于 2010-06-24T13:44:25.403 に答える
0

クライアント側では、netstatを実行したときにどのポートを探していましたか?

クライアントが接続を行うとき、エフェメラルポートを使用するためです。これは、既知のポート番号の最大値を超える空きポート番号を使用することを意味します。したがって、クライアントは予想とは異なるポート番号を使用している可能性があります。

そして、ネットワークストリームの問題については、何が悪かったのかを判断するためにコードを確認する必要があります。

于 2010-06-24T13:54:44.410 に答える