2

NetworkStream.Read と NetworkStream.Write を使用して 88 バイトの生データ (文字列ではない) を送信するプログラムがあります。

バイト番号 58 の値はたまたま 10 (改行) です。このバイトが受信されると、受信プログラム インスタンス ストリームは読み取りを停止し、生データの読み取りではなく、ReadLine のように動作します。

シナリオは一貫しており、一度に 32 バイトを読み取るように変更すると、32 を読み取ってから 26 (合計 58) を読み取り、同じバイトで停止します。

これは、ポート 21 を使用してインターネット経由で接続された異なるマシンで 2 つのプログラム インスタンスを実行した場合です。同じマシンで両方のインスタンスを実行すると、88 バイト全体が問題なく受信されます。

Network Monitor を使用して 30 バイトがどこで失われるかを確認しますが、ここで提案を求めたり、誰かが同様の問題に直面したかどうかを尋ねたりすることにしました。

編集:コードは次のとおりです。

これがコードです。1 つのストリームからデータを読み取り、双方向で動作するもう 1 つのストリームに書き込みます。

class ProxyConnection
{        
 private NetworkStream clientStream;
 private NetworkStream serverStream;
 public ProxyConnection()
 {
..            clientStream = tcpClient.GetStream();
            serverStream = tcpServer.GetStream();
..}

 private void RouteFromClientToServer()
 {
   Message message;
   while (true)
   {
     try
     {
       message = ReadMessageFromClient();
       ValidateMessage(message);
       SendMessageToServer(message);
     }
     catch(IOException e)
     {
      Logger.getInstance().log(e.Message);
      break;
     }
    }
}
        private Message ReadMessageFromClient()
        {
            Message message = new Message();
            message.bytes = new byte[MESSAGE_SIZE];
            message.bytesCount = clientStream.Read(message.bytes, 0, MESSAGE_SIZE);
            Logger.getInstance().log("Size ( " + message.bytesCount + " ) From Client");
            return message;
 }



    private void SendMessageToServer(Message message)
    {      
        serverStream.Write(message.bytes, 0, message.bytesCount);
        Logger.getInstance().log("Size ( " + message.bytesCount + " ) To Server");
        serverStream.Flush();
    }


}
4

2 に答える 2

0

どのポートを使用していますか?プロキシサーバーはありますか?

具体的には、ポート21(FTP)を使用している場合、一部のプロキシサーバーではパッシブFTPの特殊な処理が行われます。これには、プロキシがトラフィックをスキャンする必要があると思います。特に、コマンドが無効な場合は、プロキシがソケット接続を閉じるのがわかります。

回避策は...別のポートを使用することです。

于 2011-12-29T12:03:00.653 に答える
0

TCP ソケットは、一度に送受信するバイト数を特に気にしません。データまたはスペースが利用可能な場合は、処理できる限り送受信します。スペースまたはデータがない場合、送信または受信は、できることができるまでブロックできます。しかし、バッファーに 10 バイトのスペースがあり、50 バイトを送信する場合、ソケットは喜んで 10 バイトをバッファーに詰め込み、「10 バイトが送信されました。残りを少し送信してみてください」と言います。同様に、10 バイトが使用可能で、50 バイトが必要な場合、ソケットは「ここに 10 があります。もっと多くなるまでやってください」と言います。ソケットでの後続の受信または送信は、通常、データまたはスペースが増えるまでブロックされ、その時点で利用可能な限り読み取りまたは書き込みが行われます。そのため、シャッフルできたデータの量を返します。

ストリームを介したテキストの処理を容易にする魔法 (10 を送信する際の自動フラッシュなど) が発生している可能性は十分にあります。しかし、もう一度読むと、より多くのデータが得られるはずです。読み取りが 0 バイトを返さない限り、これは通常、接続が閉じられており、ソケットを閉じる/破棄する前にソケットをシャットダウンしていないことを意味します。

于 2011-12-28T14:25:28.860 に答える