2016-11-04 19 views
0

2つのコンピュータ間で名前付きパイプを介していくつかのバイトを送信したいとします。クライアントは65537バイトを送信し、PipeStream.Write()はバイトが送信されたものとして返されますが、サーバーはこれらのバイトを受信しません。なぜクライアントは私に嘘をついていますか?私は私のバイトをチャンクで送ることができると思うが、PipeStream.Writeが私のためにそれをするという印象の下にあった。マシンの1つは仮想、1つは物理的です。クライアントが1バイト少ない(65536バイト)を送信すると、サーバーはそれらをすべて受信します。別のケースでは、両方のマシンが物理的な場合、65537バイトもすべて正常に受信されます。動作を再現するコードは次のとおりです。他のマシン上にあるマシンとtest.exe 65537 other.comp.nametest.exe 100000 -を実行します。ネットワークパイプに多くのデータを書き込むときにバイトが失われる

class Program 
{ 
    const string PipeName = "TestPipe"; 

    static void Main(string[] args) 
    { 
     int bufferSize = int.Parse(args[0]); 

     if (args[1] == "-") 
     { 
      using (var server = new NamedPipeServerStream(PipeName, PipeDirection.InOut, 1, 
       PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) 
      { 
       server.WaitForConnection(); 

       byte[] result = new byte[bufferSize]; 

       for (int offset = 0; offset < bufferSize;) 
       { 
        IAsyncResult asyncResult = server.BeginRead(result, offset, bufferSize - offset, null, null); 

        asyncResult.AsyncWaitHandle.WaitOne(); 

        int bytesRead = server.EndRead(asyncResult); 

        if (bytesRead == 0) 
        { 
         Console.WriteLine("Client closed the pipe after {0} bytes.", offset); 
         return; 
        } 

        offset += bytesRead; 
       } 

       Console.WriteLine("All bytes are read."); 
      } 
     } 
     else 
     { 
      using (var client = new NamedPipeClientStream(args[1], PipeName, PipeDirection.InOut, PipeOptions.Asynchronous)) 
      { 
       client.Connect(1000); 

       byte[] buffer = new byte[bufferSize]; 

       client.Write(buffer, 0, buffer.Length); 

       client.WaitForPipeDrain(); 

       Console.WriteLine("All bytes are written."); 
      } 
     } 
    } 
} 
+0

これはベルを鳴らします.64 KBのパイプバッファ制限を持つVMがあります。私たちがなぜこの味を推測しなければならないのか分かりませんが、おそらく[これは役に立ちます](http://home.gna.org/pysfst/tests/pipe-limit.html)。カーネルにパッチを張ってください:-P。 4096は永遠に良いI/Oバッファサイズです。 –

答えて

0

VMの制限が64KBの場合、C#が私にあるという事実を受け入れました。回避策は、バイトをチャンクで送信し、それ以上は話しません。

0

あなたはPipeTransmissionMode.Byteであなたのパイプを使用しています。このモードでデータを送信し、処理を終了することが期待されます。この場合、サーバーコードでは0バイトの読み込みを停止しないでください。代わりにserver.IsConnectedをチェックしてください。クライアントがパイプを閉じるとすぐに、すべてのデータが送信されます。この値はfalseになります。その間にいくつかのbytesRead == 0の読み値が得られるかもしれません。

関連する問題