2017-11-19 5 views
1

TCP 클라이언트를 만들었지 만 연결이 잘되었지만 연결을 닫지 않고 서버로부터 메시지를받는 방법이 약간 혼란 스럽습니까?내 프로그램이 TCP 연결로 멈추는 것을 막는 방법 C#

현재 나의 접근 방식은 네트워크 스트림 읽기 방법을 통해 공동 루틴을 실행하는 것이었지만 내 프로그램이 멈추었 기 때문에 잘못된 접근 방식으로 인해이를 수정하는 방법을 잘 모릅니다.

연결을 유지하고 메시지가 서버에서 도착할 때 읽을 수 있습니다.

public int Recieve(byte[] readBuffer) 
    { 
     if (!IsConnected) 
      return -1; //-1 signifies an error aka we are disconnected 

     try 
     { 
      // NetworkStream is from TcpClient.GetStream() 
      bytesRead = _networkStream.Read(readBuffer, 0, readBuffer.Length); 
     } 
     catch (Exception e) 
     { 
      IsConnected = false; 
      Debug.Log(e); 
      bytesRead = -1; 
     } 

     return bytesRead; 
    } 

어떻게 난 내 프로그램을 잠금이 발생하지 않도록 않습니다

// the idea is to run a coroutine for recieving messages 
private IEnumerator<float> _RunTCPSocket() 
{ 
    int timer = DateTime.Now.Second; 
    byte[] readBuffer = new byte[1024]; 

    while (SocketManager.IsConnected) 
    { 
     // this is the keep alive packets to server to prevent timeout on server side 
     if (DateTime.Now.Second - timer > KeepAliveRate) 
     { 
      Debug.Log("Sending"); 
      timer = DateTime.Now.Second; 
      SocketManager.Send(null); 
     } 

     int msgLength = SocketManager.Recieve(readBuffer); 
     if (msgLength > 0) 
      Debug.Log(Encoding.ASCII.GetString(readBuffer, 0, msgLength)); 

     yield return Timing.WaitForOneFrame; 
    } 
} 

이 수신 방법에 대한 코드는 다음과 같습니다

이 내가 현재 설정이 무엇인가?

+2

다른 스레드에서 네트워크 작업을해야합니다. 비동기 기능을 사용하여 읽기, 보내기 및 연결하고 네트워크를 청취하거나 이러한 기능은 무언가 (오류/성공)가 발생할 때까지 차단됩니다. – Programmer

+0

BackgroundWorker를 사용해야합니다. https://msdn.microsoft.com/es-es/library/cc221403(v=vs.95).aspx –

+0

흠, 비동기 메서드를 살펴 봤지만 예제가 없습니다. 유일한 TCP 클라이언트 예제입니다. 그들은 동기식이었다. – Sir

답변

1

당신은 당신의 프로그램이 책임을 만들기 위해/종료에게 방법을 시작 사용할 수 있습니다

Document from microsoft

당신은 BeginReceive 방법을 사용하여 그렇게 개인적으로 너무 복잡 것을 알 수 있습니다, 내가 그것을 사용하기 쉬운 생각하지 않습니다 .
대안은 Task 내에서 읽기/쓰기 메소드를 호출하는 것입니다.
세 번째 옵션은 서버 측에서 사용 된 TcpListener과 클라이언트 측에서 사용한 TcpClient입니다. 이 두 클래스는 밑줄 TCP 소켓의 래퍼 일뿐입니다. 이러한 래퍼는 스트림 및 비동기 메서드를 사용하여 훨씬 쉽게 작업을 수행 할 수 있습니다. 작업 작업을위한 리처드 블룸

업데이트

코드에 의해
C# 네트워크 프로그래밍 : 당신이 C와 함께 # 네트워크 프로그래밍에 대한 자세한 내용을 원한다면

, 내가보기 엔이 책을 recomment :

public event EventHandler<ReceiveDataEventArgs> DataReceived = null; 
    public void StartReceive() 
    { 
     Task.Run(() => 
     { 
      while (true) 
      { 
       var bytesRead = _networkStream.Read(readBuffer, 0, readBuffer.Length); 
       DataReceived?.Invoke(this, new ReceiveDataEventArgs 
       { 
        Data = bytesRead 
       }); 
      } 
     }); 

    } 

    public class ReceiveDataEventArgs : EventArgs 
    { 
     public byte[] Data { get; set; } 
    } 
+0

현재 작업에서 읽기를 사용하고 있지만 새 메시지가 서버에서 도착하여 처리되는 경우 자주 확인하는 방법은 무엇입니까? 그게 뭔가 내가 좋은 코드 예제를 사용하여 작업을 찾을 수 없습니다. – Sir

+0

데이터 만받는 클라이언트 코드를 사용하면 Read 메서드를 Task 내부의 무한 루프에 넣을 수 있습니다.일단 데이터를 수신하면 클라이언트 클래스를 사용하는 이벤트 및 다른 클래스를 올리면 해당 이벤트를 구독하고 수신 된 데이터를 처리 할 수 ​​있습니다. –

+0

작업 작업을위한 업데이트 코드 샘플이 있습니다. 몇 년 동안 소켓으로 작업하지 않았으므로 코드에 구문 문제가 거의 없을 수도 있지만 프로그램이 책임 져야한다고 확신합니다. –