2014-08-27 3 views
2

한 번받은 후 두 번째 읽으려고 할 때 문제가 있습니다. 필자는 쓰기가 대기 중이며 응용 프로그램을 중지 할 때만 통과한다고 생각합니다. 어떻게 든 첫 번째 읽기 후에 전체 메시지를 읽은 후에도 차단하고 있습니다. 내 목표는 들어오는 메시지를 읽고, 처리 한 다음 연결된 클라이언트에게 메시지를 보내고, 클라이언트가 메시지를 수신했음을 인정하는 메시지를 기다리는 것입니다. 여기에 내가 가진 코드는 지금까지TcpClient가 두 번째 시도에서 읽을 수 없습니다.

나는 클라이언트 그런 다음 클라이언트가 나는 다른 스레드에서의 통신의 처리를 던져 연결 후

 this.tcpListener = new TcpListener(IPAddress.Loopback, 14000); 
     this.listenThread = new Thread(new ThreadStart(ListenForClients)); 
     this.listenThread.Start(); 

을 기다리고 별도의 스레드에서 리스너를 시작

 this.tcpListener.Start(); 
     tcpClient = this.tcpListener.AcceptTcpClient(); 
     Thread clientThread = new Thread(new ParameterizedThreadStart(ProcessMessage)); 
     clientThread.Start(tcpClient); 

processMessage를 방법은 follwing을

public void ProcessMessage(object client) 
    { 
     if (client != null) 
     { 
      tcpClient = client as TcpClient; 
     } 

     this.messageReceived = false; 

     NetworkStream clientReadStream = tcpClient.GetStream(); 


     byte[] message = new byte[tcpClient.ReceiveBufferSize]; 
     int byteRead = 0; 

     while (!this.messageReceived) 
     { 
      byteRead = 0; 
      if (tcpClient.Connected) 
      { 
       try 
       { 
        byteRead = clientReadStream.Read(message, 0, tcpClient.ReceiveBufferSize); 
       } 
       catch (Exception) 
       { 
        throw; 
       } 

       if (byteRead == 0) 
       { 

        break; 
       } 
       else 
       { 
        System.Text.UTF8Encoding encoder = new System.Text.UTF8Encoding(); 
        this.request = encoder.GetString(message, 0, byteRead); 
        if (!string.IsNullOrEmpty(this.request)) 
        { 
         this.messageReceived = true; 
        } 

       } 
      } 
     } 
    } 
,369 같다

그럼 내가 다시 클라이언트로 메시지를 보낼 필요하고 메시지를 처리 ​​한 후, 나는 ...보고 어떤 방향으로 같이 sendData

public void SendData(string data) 
     { 
      if (tcpClient != null) 
      { 

       if (tcpClient.Connected) 
       { 
        try 
        { 
         System.Text.UTF8Encoding encoder = new System.Text.UTF8Encoding(); 
         NetworkStream clientWriteStream = tcpClient.GetStream(); 

         byte[] buffer = encoder.GetBytes(data); 
         clientWriteStream.Write(buffer, 0, buffer.Length); 
         clientWriteStream.Flush(); 

         this.messageReceived = false; 

        } 
        catch 
        { 
         throw; 
        } 
       } 
      } 

     } 

확실하지라는 방법을 통해 다른 스레드에서 모든 주셔서 감사합니다 그렇게 제안 또는 방향을 미리 지정하십시오.

+1

이 TCP가 _messages_ 처리하는 기대의 고전적인 사례인가를 읽을 투약하는 경우? TCP는 연결의 한쪽 끝에서 밀어 넣은 바이트가 같은 순서로 중복되지 않고 다른 쪽 끝이 떨어지는 것을 보증합니다. 메시지의 개념은 없습니다. 한 번에 하나 이상의 메시지를 수신하지 못했는지 확인하기 위해 버퍼를 검사 했습니까? – HABO

+0

이 특별한 경우에 두 엔티티간에 xml을 전달하려고합니다. 통신은 앞뒤로 한 번에 한 단계 씩 수행되며 한 번에 하나의 클라이언트 만 수행됩니다. 그래서 나는 한 전화가오고 다른 사람이 다른 사람에게 편지를 쓸 때까지는 아무 것도 올 것이라고 가정 할 수 있습니다. – crossroad

+1

@crossroad : 댓글을 잘못 이해했습니다. 요점은 xml 데이터가 단일 읽기에 도착한다는 것을 알 수 없다는 것입니다. 전체 xml 메시지를 가져 오기 위해 여러 번 읽을 수 있습니다. 나는 [주제에 대한 블로그 게시물]을 가지고있다 (http://blog.stephencleary.com/2009/04/message-framing.html). –

답변

1

this.messageReceived = true; 당신은 받아 봐 메시지를 가지고 때 condation는 동안 동안 첫 번째 메시지는 recived 때, 이것은

이 코드 시도 ... you'r는 동안이 종료됩니다 받아 봐, becuase한다 (this.messageReceived!) :

public void ProcessMessage(object client) 
{ 
    if (client != null) 
    { 
     tcpClient = client as TcpClient; 
    } 

    this.messageReceived = false; 

    NetworkStream clientReadStream = tcpClient.GetStream(); 


    byte[] message = new byte[tcpClient.ReceiveBufferSize]; 
    int byteRead = 0; 

    while (true) 
    { 
     byteRead = 0; 
     if (tcpClient.Connected) 
     { 
      try 
      { 
       byteRead = clientReadStream.Read(message, 0, tcpClient.ReceiveBufferSize); 
      } 
      catch (Exception) 
      { 
       throw; 
      } 

      if (byteRead == 0) 
      { 

       break; 
      } 
      else 
      { 
       System.Text.UTF8Encoding encoder = new System.Text.UTF8Encoding(); 
       this.request = encoder.GetString(message, 0, byteRead); 
       if (!string.IsNullOrEmpty(this.request)) 
       { 
        this.messageReceived = true; 
       } 

      } 
     } 
    } 
} 

코드의이 부분에서주의 :

if (byteRead == 0) 
    { 

     break; 
    } 
    else ... 

때문에 읽기 방법은 다시 종료됩니다 동안 어떤 일이 ...

관련 문제