2012-03-19 19 views
1

ソケットからデータを読み取ろうとしていますが、ストリーム全体を読み取ろうとするとプログラムがハングします。エラーも例外もありません。NetworkStreamから読み取ろうとすると、プログラムに例外またはエラーは発生しません。

私は手動で4バイトと言うことができますが、それは動作しますが、サーバーが送信するデータの正確なサイズはわかりません。したがって、ストリーム全体を読みたいと思います。私は間違って何をしていますか?

ReadToEnd()を呼び出すとハングします。

Stream input = socket.GetStream(); 

byte[] request = new byte[5]; 

input.Write(request, 0, 5); //send request 

StreamReader reader = new StreamReader(input); 

if (input.CanRead == true) 
{ 
    string test = reader.ReadToEnd(); 
} 
+1

"クラッシュ"とはどういう意味ですか?文字通り無限に長いストリームを読んでいます。プログラムがシングルスレッドの場合、ReadToEnd()を完了していない可能性があります。 –

+0

さて、私はそれがハングアップすると、それはその行を通過しないと言う必要があります。しかし、もし私が5バイトを4の代わりに言うと、それは同じ方法でハングする。 – benjgorman

+1

ストリームリーダーのヘルプページから: ReadToEndは、ストリームが終了に達したことをストリームが認識していることを前提としています。 ReadToEndは、要求があっても接続を終了しない場合にのみデータを送信する対話型プロトコルの場合、終了に達しないために無期限にブロックされる可能性があります。避ける必要があります。 サーバーからデータが送信されたことをどのように知っていますか? –

答えて

1

あなたのコードは、ストリームの長さを知ることはできません。終了していない可能性があります。以下の例のサーバーとクライアントがある(決してが、これは堅牢な実装である)が、次のコードを検討する場合は、要求を送信し、応答を受信する方法を参照してください。

public class Server 
    { 
     private readonly Thread _listenThread; 
     private readonly TcpListener _tcpListener; 

     public Server() 
     { 
      _tcpListener = new TcpListener(IPAddress.Any, 3000); 
      _listenThread = new Thread(Listen); 
      _listenThread.Start(); 
     } 

     private void Listen() 
     { 
      var tcpListener = _tcpListener; 

      if (tcpListener != null) 
      { 
       tcpListener.Start(); 
      } 

      while (true) 
      { 
       TcpClient client = _tcpListener.AcceptTcpClient(); 
       Console.Out.WriteLine("Connection Accepted"); 
       Thread clientThread = new Thread(DoWork); 
       clientThread.Start(client); 
      } 
     } 

     private void DoWork(object client) 
     { 
      TcpClient tcpClient = client as TcpClient; 

      if (tcpClient == null) 
      { 
       throw new ArgumentNullException("client", "Must pass client in"); 
      } 

      using (NetworkStream clientStream = tcpClient.GetStream()) 
      { 
       byte[] message = new byte[1024]; 

       while (true) 
       { 
        Console.Out.WriteLine("Waiting for message"); 
        int bytesRead = clientStream.Read(message, 0, 1024); 

        if (bytesRead == 0) 
        { 
         break; 
        } 

        ASCIIEncoding encoder = new ASCIIEncoding(); 
        string received = encoder.GetString(message, 0, bytesRead); 

        Console.Out.WriteLine(String.Format("Read {0}", received)); 
        if (received.Equals("Hello Server !")) 
        { 
         byte[] buffer = encoder.GetBytes("Hello Client!"); 
         clientStream.Write(buffer, 0, buffer.Length); 
         clientStream.Flush(); 
        } 
       } 
      } 
     } 
    } 

あなたが必要になりますこのようなことをしたクライアント

static void Main(string[] args) 
    { 
     try 
     { 

      using (TcpClient clientSock = new TcpClient(IPAddress.Loopback.ToString(), 3000)) 
      { 
       using (Stream clientStream = clientSock.GetStream()) 
       { 
        ASCIIEncoding encoder = new ASCIIEncoding(); 
        byte[] helloMessage = encoder.GetBytes("Hello Server !"); 

        clientStream.Write(helloMessage, 0, helloMessage.Length); 
        clientStream.Flush(); 

        using (StreamReader streamReader = new StreamReader(clientStream)) 
        { 
         while(true) 
         { 
          char[] buffer = new char[1024]; 
          streamReader.Read(buffer,0, 1024); 

          Console.Out.WriteLine(new string(buffer)); 
         } 
        } 
       } 
      } 

      Console.ReadLine(); 
     } 
     catch (Exception) 
     { 
      // do something here 

      throw; 
     } 
    } 
関連する問題