2013-05-22 4 views
1

저는 Windows phone 용 응용 프로그램을 작성 중이며 서버와 통신하고 데이터를 전송해야합니다. SERVER는 C++로 작성되었으며 수정할 수 없습니다. CLIENT는 제가 작성해야합니다. 서버는 클라이언트가 클라이언트에 연결하여 데이터를 전송하도록 설계되었습니다. 연결은 모든 전송에 대해 열려 있습니다. C#으로 코드를 작성하면 서버에서 데이터를받을 수 있지만 처음 수신 한 후에 버퍼에서 읽은 데이터는 항상 동일합니다. 그래서 새로운 데이터를받을 수 있도록 입력 버퍼를 플러시하는 방법이 필요합니다 (데이터가 지속적으로 전송됩니다).소켓 tcp C# 입력 버퍼 지우기 방법?

http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh202858%28v=vs.105%29.aspx

덕분에 많이! : 여기에 정의 된 클래스를 사용하고 있습니다

은 내가 SocketClient.cs에서 수신이 코드를 사용 :

public string Receive() 
    { 
     string response = "Operation Timeout"; 

     // We are receiving over an established socket connection 
     if (_socket != null) 
     { 
      // Create SocketAsyncEventArgs context object 
      SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs(); 
      socketEventArg.RemoteEndPoint = _socket.RemoteEndPoint; 

      // Setup the buffer to receive the data 
      socketEventArg.SetBuffer(new Byte[MAX_BUFFER_SIZE], 0, MAX_BUFFER_SIZE); 

      // Inline event handler for the Completed event. 
      // Note: This even handler was implemented inline in order to make 
      // this method self-contained. 
      socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e) 
      { 
       if (e.SocketError == SocketError.Success) 
       { 
        // ********************************************* 
        // THIS part of the code was added to receive 
        // a vector of 3 double 
        Double[] OdomD = new Double[3]; 
        for (int i = 0; i < 3; i++) 
        { 
         OdomD[i] = BitConverter.ToDouble(e.Buffer, 8 * i); 
        } 
        // ********************************************* 

       } 
       else 
       { 
        response = e.SocketError.ToString(); 
       } 

       _clientDone.Set(); 
      }); 

      // Sets the state of the event to nonsignaled, causing threads to block 
      _clientDone.Reset(); 

      // Make an asynchronous Receive request over the socket 
      _socket.ReceiveAsync(socketEventArg); 

      // Block the UI thread for a maximum of TIMEOUT_MILLISECONDS milliseconds. 
      // If no response comes back within this time then proceed 
      _clientDone.WaitOne(TIMEOUT_MILLISECONDS); 
     } 
     else 
     { 
      response = "Socket is not initialized"; 
     } 

     return response; 
    } 

는 Connect() 메소드가 정확히 위의 링크에보고 동일합니다. 그래서 때 응용 프로그램 시작, 연결() 메소드는 다음과 같이 호출됩니다 처음에 한 번만 이루어집니다

SocketClient client = new SocketClient(); 
// Attempt to connect to server for receiving data 
      Log(String.Format("Connecting to server '{0}' over port {1} (data) ...", txtRemoteHost.Text, 4444), true); 
      result = client.Connect(txtRemoteHost.Text, 4444); 
      Log(result, false); 

, 그때 나는 초마다 업데이트됩니다 3 배의 배열을받을 필요가있다. 그래서 내가 사용 :

Log("Requesting Receive ...", true); 
      result = client.Receive(); 
      Log(result, false); 

문제는 내가 코드를 디버깅하고 실행을 중지 또한 경우() 안의받을 수 있다는 것입니다, 난 항상 같은 값을 읽고, 그 서버가 보낸 첫 번째 값입니다. 내가 기대하는 바는 client.Receive()를 호출 할 때마다 새로운 값을 얻는다는 것입니다. 그러나 이것은 붙지 않습니다.

Matlab 환경에서 동일한 클라이언트를 작성하여 비슷한 문제가 발생했습니다. 필자는 입력 버퍼를 읽기 전에 flushinput (t) 함수를 사용하여이 문제를 해결했습니다. 이 방법으로 나는 서버가 보낸 마지막 데이터를 항상 읽을 수있었습니다. 그 비슷한 기능을 찾고 있어요.

입력 버퍼의 크기는 수신 할 것으로 예상되는 데이터와 동일하게 고정됩니다.이 경우 24 바이트 (3 * sizeof (double))입니다.) ..

시간 내 주셔서 감사합니다!

+0

가 보이는 : 당신은 당신이 코드를 게시에서 본 표시 고정 버퍼를 가지고 있고 SocketAsyncEventArgs 통해 수신하지 않기 때문에, 당신은 그것을 취소 할 수);'while (true) '루프 (링크 된 기사의)에서. – oleksii

+1

기본적으로 코드에는 버그가 있지만 코드는 포함하지 않았습니다. 버퍼 내용은 async-receive가 완료 될 때마다 변경되어야합니다. 특히 얼마나 많은 바이트가 수신되었는지 (전체 버퍼를 거의 읽지는 않는지) 확인하는 것에 유의하십시오. 관련있는 수신/읽기 코드를 표시하십시오. 우리는 짐작만으로 해결할 수 없습니다. –

+0

관련 코드를 추가했습니다. 도움을 주셔서 감사합니다 !! – Emanuele

답변

1

oleksii가 맞다면, client.Receive()를 루프로 호출해야합니다. 코드의 수신 섹션을 다루는 스레드를 시작하도록 선택할 수 있습니다. 또한 client.Receive()가 버퍼에서 수신을 시도 할 것이고 사용할 수있는 데이터가없는 경우 막히게됩니다.

0

주요 질문은 ** 입력 버퍼를 지우는 방법 이었습니까? ** 아니면 내가 틀린거야? =!

그럼에도 불구하고; 당신은`결과 = client.Receive (이 방법을 둘 필요가 같은

Array.Clear(e.Buffer, 0, e.Buffer.Length);