2009-05-07 4 views
3

아래 코드는 TCP 클라이언트 스트림에서 읽는 모든 것을 읽습니다. 다음 반복에서는 Read() (데이터 대기 중일 때) . 읽지 않을 것을 어떻게 보장 할 수 있습니까? 시간 제한을 낮게 설정해야하며 장애가 발생하면 예외에 응답해야합니까? 아니면 더 좋은 방법이 있을까요?streamreader가 데이터 대기를 기다리지 않도록하십시오.

TcpClient tcpclnt = new TcpClient(); 
tcpclnt.Connect(ip, port); 

Stream stm = tcpclnt.GetStream(); 

stm.Write(cmdBuffer, 0, cmdBuffer.Length); 

byte[] response = new Byte[2048]; 

MemoryStream ms = new MemoryStream(); 
byte[] buffer = new Byte[2048]; 
int length; 
while ((length = stm.Read(buffer, 0, buffer.Length)) > 0) 
    ms.Write(buffer, 0, length); 

byte[] response = ms.ToArray(); 


tcpclnt.Close(); 

답변

0

서버에 "연결 유지"가 설정되어 있습니까?

요청한 동안 빈 바이트 스트림을 보내는 서버가 있습니다.

"계속 연결 유지"를 선택하면이 작업이 중지됩니다.

+0

tnx 4 답장. 서버에서 아무것도 변경할 수 없습니다. 또한, 만약 내가 tcp 클라이언트 타임 아웃을 1 초로 설정하면 타임 아웃되고 예외가 발생합니다. 그래서, 아니오, 나는 빈 바이트를 얻지 못하고있다. – flamey

+0

중단 점이나 카운터를 추가하여 시도 했습니까? 매달려 있는지 또는 루프에 걸렸는지 확인하려는 시도가 있습니까? –

+0

루프에 걸리지 않았습니다. 그것의 붙어있어 읽기(). 두 개의 연속적인 stm.Read (buffer, 0, buffer.Length) 라인으로 루프를 대체하면 처음으로 20 바이트를 받고 다음 라인으로 넘어갑니다. 또는 버퍼 크기를 10로 설정하면 두 번 반복하여 20 바이트를 얻은 다음 다음, 세 번째 반복에 앉을 것입니다. – flamey

1

TcpClient에는 내가 재생할 두 가지 속성이 있습니다.

  1. NoDelay 가져 버퍼가 가득하지 수신 또는 송신 지연 비활성화 값을 설정한다.
  2. ReceiveTimeout 가져 읽기 작업이 어쩌면 당신은 멀티 스레딩을 사용한다
+0

정답은 (2)이어야한다고 생각합니다. http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.receivetimeout.aspx –

+0

NoDelay는 송신 버퍼에만 영향을 미칩니다. 5ms 정도 지나면 결국 전송됩니다. https://en.wikipedia.org/wiki/Nagle's_algorithm – servermanfail

1

을 시작 일단하여 TcpClient가 데이터를 수신하기 위해 대기하는 시간을 설정합니다. 한 스레드는 데이터를 기다려야하고 다른 스레드는받은 데이터를 처리해야합니다.

+0

실용적인 해결책이 있지만 여기에 시나리오가 있습니다 (화면에 잔인 함이 있습니다.) : POP3 프로토콜을 상상해보십시오. 라인을 보내고 라인을 수신하십시오. .와 "." 메시지의 끝을 의미하는 자체 회선. 그러나 이제는 서버가 "Username :"을 보내는 다른 프로토콜을 상상해보십시오. CR/LF가 아닙니다. StreamReader.ReadLine()은 영원히 중단됩니다. POP3는 괜찮지 만 1 바이트를 변경하고 LOC는 물론 다른 도식적 접근법을 사용하면 나에게 잘못된 것처럼 들립니다. – servermanfail

0
var socket = new System.Net.Sockets.TcpClient(); 
      socket.NoDelay = true; 
      socket.Connect(uri.Host, port); 
      var ns = socket.GetStream(); 
      int timeout = 500; //ms 
      DateTime lastReceived = DateTime.Now; 
      string buffer = ""; 
      while (true) 
      { 
       if (ns.DataAvailable) 
       { 
        var b = ns.ReadByte(); 
        buffer += b + ", "; //customise this line yourself 
        lastReceived = DateTime.Now; 
        continue; 
       } 
       if (lastReceived.AddMilliseconds(timeout) < DateTime.Now) break; 
       System.Threading.Thread.Sleep(timeout/5); 
      } 
관련 문제