0

TcpClientバッファからバイト配列にデータを読み込もうとしています。

private byte[] excessData;
public bool receiveMessage(ref string recvStr, string daddy = "")
{
    recvStr = "";
    CSocket_PacketProtocol packprot = new CSocket_PacketProtocol(0, this);

    WriteDebugWithTimestamp("receiveMessage obtaining client NetworkStream - daddy = " + daddy);
    NetworkStream nStream = client.GetStream();
    WriteDebugWithTimestamp("receiveMessage client NetworkStream obtained, entering receive loop");

    int bytesRead = 0;
    do
    {
        if (!packprot.done)
        {
            try
            {
                byte[] inStream = new byte[10025]; //We'll read into this stream

                int buffSize = client.ReceiveBufferSize;
                WriteDebugWithTimestamp(String.Format("Starting nStream.Read"));
                WriteDebugWithTimestamp(String.Format(String.Format("buffSize={0} -- inStream.Length={1}", buffSize, inStream.Length)));

                bytesRead = nStream.Read(inStream, 0, buffSize); //Recieve data from stream to inStream, return amount of bytes read

                WriteDebugWithTimestamp(String.Format("receiveMessage bytesread: {0}", bytesRead.ToString()));
                WriteDebugWithTimestamp(String.Format("receiveMessage client.Connected: {0}", client.Connected.ToString()));

                ../Cut

クライアントがSystem.Net.Sockets.TcpClient。例外はで発生しnStream.Readます。

Debian-6.0_64 / Mono2.11.2で実行した場合の出力Mono --runtime=v4.0.30319 Program.exe

receiveMessage obtaining client NetworkStream - daddy = 
receiveMessage client NetworkStream obtained, entering receive loop
receiveMessage this.excessData == null: True -- excessdata.length=n/a
Starting nStream.Read
buffSize=87380 -- inStream.Length=10025

System.ArgumentOutOfRangeException: Argument is out of range.
Parameter name: offset+size exceeds the size of buffer
  at System.Net.Sockets.NetworkStream.Read (System.Byte[] buffer, Int32 offset, Int32 size) [0x00000] in <filename unknown>:0 
  at SocketOperations.CSocketOperations.receiveMessage (System.String& recvStr, System.String daddy) [0x00000] in <filename unknown>:0 
  at SocketServerV3_Demo.CDownloadServer_ClientHandle..ctor (System.Net.Sockets.TcpClient client) [0x00000] in <filename unknown>:0 
  at SocketServerV3_Demo.Program.handleNewConnection (System.Net.Sockets.TcpClient client) [0x00000] in <filename unknown>:0 

buffSizeはバイト配列の長さよりもはるかに大きいですが、Windowsでまったく同じプログラムを実行した場合(monoなし、試していない場合)、その例外は発生しません。何が得られますか?そして、どうすればこれを修正できますか?バッファサイズを増やすのと同じくらい簡単ですか、それとも何か他のことが起こっていますか?私が(単に試してみるのではなく)尋ねている理由は、何が起こっているのか見当がつかず、正しく行われるようにしたいからです。

この動作の背後にある理由を調べたいと思います。このように見ると、Windowsでもクラッシュすると予想されるからです。バッファのサイズがOSによって決定され、Windowsの場合は、バイト配列のサイズよりも小さい/等しい場合を除いて、誰かが説明できますか?

4

1 に答える 1

6

MonoTcpClient.ReceiveBufferSizeはWindowsよりも大きいようです。

MSDN Docsによると、デフォルトは8192バイトです。

Monoの実装を確認GetSocketOption()したところ、基盤となるソケットを呼び出しているため、オペレーティングシステムのデフォルトを使用しています。

3つのオプションがあります。

  1. を使用して、ソケットの受信バッファサイズを変更しますclient.ReceiveBufferSize = new_size
  2. 十分な大きさのバッファーを割り当てます。
  3. バッファが保持できる以上のデータを読み取らないでください。

    var max_size = Math.Min (client.ReceiveBufferSize, buffer.Length);
    bytesRead = nStream.Read(inStream, 0, max_size);
    
于 2012-10-20T20:57:39.680 に答える