2012-04-10 11 views
5

StreamSocket API를 사용하여 서버에 스트리밍 연결을 수행하는 Windows 8/WinRT 용 응용 프로그램이 있습니다. 즉, 서버는 메타 데이터로 클라이언트에 데이터를 스트리밍하고 언제든지 연결을 끊을 수 있습니다.WinRT StreamSocket 처리 (서버 측과 클라이언트 측 모두)

내가 겪고있는 문제는 서버가 분리되었을 때이를 감지하는 방법을 모른다는 것입니다. StreamSocket 클래스에는 입력 스트림이나 출력 스트림 또는 연결 상태와 관련이있는 DataReader/DataWriter 클래스에 이벤트 나 속성이없는 것으로 나타납니다.

그 외에 서버 측이 클라이언트와의 연결을 끊으면 ReadAsync 메서드가 실패하지 않습니다. 대신, 내가 말할 수있는 한 작업이 성공하고 버퍼에 채워지는 데이터는 서버가 보낸 마지막 것입니다 (즉, 내부 버퍼를 지우지는 못합니다. ReadByte를 호출 할 때마다 버퍼). 이후에 ReadAsync를 호출 할 때마다 서버가 연결을 끊기 전에 마지막으로 보낸 내용으로 버퍼를 다시 채 웁니다.

public async Task TestSocketConnectionAsync() 
    { 
     var socket = new StreamSocket(); 
     await socket.ConnectAsync(new HostName(Host), Port.ToString(), 
      SocketProtectionLevel.PlainSocket); 
     var dr = new DataReader(socket.InputStream); 
     dr.InputStreamOptions = InputStreamOptions.Partial; 

     this.cts = new CancellationTokenSource(); 
     this.listenerOperation = StartListeningAsync(dr, cts); 
    } 

    public async Task StartListeningAsync(DataReader dr, CancellationTokenSource cts) 
    { 
     var token = cts.Token; 
     while (true) 
     { 
      token.ThrowIfCancellationRequested(); 
      var readOperation = dr.LoadAsync(1024); 
      var result = await readOperation; 
      if (result <= 0 || readOperation.Status != Windows.Foundation.AsyncStatus.Completed) 
      { 
       cts.Cancel(); // never gets called, status is always Completed, result always > 0 
      } 
      else 
      { 
       while (dr.UnconsumedBufferLength > 0) 
       { 
        byte nextByte = dr.ReadByte(); 

        // DriveStateMachine(nextByte); 
       } 
      } 
     } 
    } 

답변

9

때로는 메타 태그와 클라이언트, 서버 스트림 데이터를, 말을하는 것입니다, 언제든지 해제 할 수 있습니다 : 여기에 코드의 단순화 된 버전입니다. 내가 겪고있는 문제는 서버 연결이 끊어졌을 때 어떻게 감지 할 수 있는지 전혀 모른다는 것입니다.

"우아한"소켓 클로저는 다른 쪽에서 길이가 0 인 것으로 감지 될 수 있습니다. 즉, 이는 보통의 엔드 오브 스트림처럼 작동합니다.

"abortive"소켓 클로저는 더 까다 롭습니다. have to send data은 다른 쪽이 닫혔 음을 감지하고 쓰기가 실패하면 추가 읽기 또는 쓰기가 실패합니다 (예외가 있음). 프로토콜에 따라 데이터를 전송할 수 없으면 제한 시간이 만료되고 연결을 종료 한 후 연결이 잘못되었다고 가정해야합니다. :(

응용 프로그램에 따라 "유산"소켓 폐쇄 될 수있다 정상 - 특히, 매우 바쁜 서버는 그들이 피 (더 빨리 자원을 확보 할 수 있기 때문에 자신의 연결을 종료 클램프 기록 될 수 있습니다 - 스텝 소켓 종료 핸드 셰이크).

가 하나의 입력 또는 출력 스트림의 StreamSocket 클래스의 모든 이벤트 또는 속성으로 표시하지 않거나

연결과 아무 상관이 DataReader를/DataWriter 클래스에 대한 상태.

DataReader/DataWriter은 "연결"과 관련이 없습니다. 실제로는 단지 BitConverter이며 이번에는 더 잘 설계되었습니다.

이유는 Socket.Connected is nearly useless and definitely misleading이기 때문에 "연결됨"속성이없는 것 같습니다.


나는 StreamSocket.InputStream.ReadAsync를 사용하는 대신 직접 그냥 어쨌든 바이트를 읽어 들이기 때문에, DataReader를 사용하려고 할 것입니다. DataReader에있는 버그를 발견 한 것 같습니다. 에보고해야합니다. InputStream.ReadAsync이 예상대로 작동하면보고해야합니다. 또한 this related forum post을 참조하십시오.

+1

알 수있는 좋은 정보입니다.고맙습니다. DataReader.ReadAsync 문제는 버그 인 것 같습니다. Microsoft 내에서 해당 팀이이를 인식하고 있으므로 해결 될 것으로 기대됩니다. 그 동안, 필자는 자신의 IBuffer (WindowsRuntimeBuffer.Create에서)에 대해 InputStream.ReadAsync를 호출하는 제안을 시도했지만 작동하지 않을뿐만 아니라 지연 시간이 눈에 띄게 줄어든 것으로 보입니다. –

+0

이 (가)이 이전 게시물을 발견했습니다. @ JeremyBell이'InputStream.ReadAsync'에 대해 열어 본 사용자 음성 버그는 무엇입니까? 지금까지 해결 되었습니까? 나는 또한 입력 스트림에 이상한 행동을하는 것으로 보입니다. 서버에서 응답을 계속해서 쌓아 두어야합니다. 새 데이터를 서버에 보내기 전에 소켓에서 모든 데이터를 읽으 려합니다. http://stackoverflow.com/questions/27533703/how-to-read-all-the-available-data-from-a-winrt-streamsocket-and-empty-the-input?noredirect=1#comment43496033_27533703을 참조하십시오. – philk

관련 문제