2016-05-02 8 views
1

私はSslStreamを介して通信しているTcpClientとServerを作成しました。 通信は機能しますが、クライアントからサーバーにメッセージを送信すると、最初にサーバーは1バイトを読み取り、次のステップで残りのメッセージを読み取ります。例:私はクライアントを経由して「テスト」を送信すると、サーバーは最初の「T」を受信した後、「EST」SslStream EndReadは最初の1バイトを取得します

ここでは

public void Send(string text) { 
     byte[] message = Encoding.UTF8.GetBytes(text); 
     SecureStream.BeginWrite(message, 0, message.Length, new AsyncCallback(WriteCallback), null); 
    } 

    private void WriteCallback(IAsyncResult AR) { 

    } 

そして、ここにコードを送信するために、クライアントのコードですサーバーは読み取りに使用します

private SslStream CryptedStream = ...; 
    private byte[] buffer = new byte[1024]; 

    public void BeginReadCallback(IAsyncResult AsyncCall) { 

     // initialize variables 
     int bytesRead = 0; 

     try { 
      // retrieve packet 
      bytesRead = CryptedStream.EndRead(AsyncCall); 

      // check if client has disconnected 
      if (bytesRead > 0) { 
       // copy buffer to a temporary one 
       var temporaryBuffer = buffer; 
       Array.Resize(ref temporaryBuffer, bytesRead); 

       string read = Encoding.ASCII.GetString(temporaryBuffer); 
       SetText(read); 

       // read more data 
       CryptedStream.BeginRead(buffer, 0, 1024, new AsyncCallback(BeginReadCallback), null); 

       // client is still connected, read data from buffer 
       //ProcessPacket(temporaryBuffer, temporaryBuffer.Length, helper); 
      } else { 
       // client disconnected, do everything to disconnect the client 
       //DisconnectClient(helper); 
      } 
     } catch (Exception e) { 
      // encountered an error, closing connection 
      // Program.log.Add(e.ToString(), Logger.LogLevel.Error); 
      // DisconnectClient(helper); 
     } 
    } 

私は何かを見逃しましたか? 助けてくれてありがとう

+1

ここでの質問は何ですか? A *ストリーミング接続*は決してバイトのパケットを送信しません。バイトのストリームを送信します。読み込み時には、パッケージを考慮した小さなものを取得してから、これを一貫したパッケージに再アセンブルする必要があります必要があります。 –

+0

私はストリームに精通していないので、私の未熟な私を許してください。 それは、サーバーがはるかに高速であれば、私は "t" "e" "s" "t"を受け取ることを意味するでしょうか? –

+1

あなたはそれを受け取ることもできますし、 'tes'、' t'、 't'、' est'や 'te'、' st'を受け取ることもできます。これは、多くのこと、速度、ハードウェア(コンピュータ、ルータ、2つのエンドポイント間のスイッチなど)とソフトウェアに依存します。要するに、あなたのコードはこれを処理できる必要があります。 –

答えて

1

Lasseは、ストリーミングAPIは1回の読み取りで特定のバイト数を返すとは保証しません。

この問題を解決する最も良い方法は、ソケットを使用しないことです。 WCF、SignalR、HTTPなどの上位レベルのAPIを使用してください。

おそらくBinaryReader/Writerを使用してデータを送信する必要があります。それは非常に簡単です。たとえば、文字列送信機能を内蔵しています。また、手動でこれらのクラスで簡単に長さ接頭辞を付けることもできます。

おそらく、あなたは非同期IOを必要とせず、使用しないでください。もしあなたが少なくともawaitを使ってコールバックを取り除くことができると主張すれば。

関連する問題