2014-06-07 3 views
4

좋아, 이것이 스택 오버플로에 대한 나의 첫 번째 질문이다. 그래서 내가 제대로 묻지 않는다면 그것으로 끝내라.D에서 비동기 소켓

기본적으로 std.socket을 사용하여 일부 비동기 소켓을 코딩하려고하지만 개념이 올바른지 잘 모르는지 확실하지 않습니다. C#에서 비동기 소켓을 사용하여 작업 한 적이 있지만 D에서는 훨씬 낮은 수준 인 것처럼 보입니다. 나는 많은 것을 연구했고 D, C/C++에 대한 많은 코드, 문서 등을 찾아 보았습니다. 그러나 개념을 올바르게 이해할 수 있는지, 그리고 어떤 사례가 있는지 잘 모르겠습니다. 나는 splat을 보았지만 매우 구식이었고 단순한 비동기 소켓 래퍼의 경우 너무 복잡했다.

올바르게 이해했다면 std.socket에 poll() 함수가 없으므로 소켓 (socket) 상태를 폴링하기 위해 select()에서 단일 소켓으로 SocketSet을 사용해야 할 것입니다.

기본적으로 소켓을 처리하는 방법은 소켓의 읽기 상태를 얻기 위해 폴링하는 것이고 성공 (값> 0)이있는 경우 receive()를 호출하여 연결 해제를 위해 0을 반환합니다. 받은 값,하지만 예상 된 바이트를받을 때까지 계속해야 할 것입니다.

물론 소켓은 비 차단으로 설정되었습니다!

맞습니까?

여기에 지금까지 작성한 코드가 있습니다.

void HANDLE_READ() 
{ 
    while (true) 
    { 
     synchronized 
     { 
      auto events = cast(AsyncObject[int])ASYNC_EVENTS_READ; 
      foreach (asyncObject; events) 
      { 
       int poll = pollRecv(asyncObject.socket.m_socket); 
       switch (poll) 
       { 
        case 0: 
        { 
         throw new SocketException("The socket had a time out!"); 
         continue; 
        } 
        default: 
        { 
         if (poll <= -1) 
         { 
          throw new SocketException("The socket was interrupted!"); 
          continue; 
         }      

         int recvGetSize = (asyncObject.socket.m_readBuffer.length - asyncObject.socket.readSize); 
         ubyte[] recvBuffer = new ubyte[recvGetSize]; 
         int recv = asyncObject.socket.m_socket.receive(recvBuffer); 

         if (recv == 0) 
         { 
          removeAsyncObject(asyncObject.event_id, true); 
          asyncObject.socket.disconnect(); 
          continue; 
         } 

         asyncObject.socket.m_readBuffer ~= recvBuffer;      
         asyncObject.socket.readSize += recv; 

         if (asyncObject.socket.readSize == asyncObject.socket.expectedReadSize) 
         { 
          removeAsyncObject(asyncObject.event_id, true); 
          asyncObject.event(asyncObject.socket); 
         } 
         break; 
        } 
       } 
      } 
     } 
    } 
} 

답변

1

그래서 기본적으로 내가 소켓 처리에 대한 가고 싶어 어떻게 소켓

그렇진 권리의 읽기 상태를 확인하기 위해 폴링이다. 일반적으로 select 주위에 이벤트 루프를 작성하여 처리해야하는 네트워크 이벤트 나 타이머 이벤트가없는 한 애플리케이션이 유휴 상태가되도록하는 것이 좋습니다. 폴링을 사용하면 새 이벤트를 지속적으로 또는 타이머를 통해 확인해야하므로 낭비되는 CPU 사이클이 발생하고 이벤트는 발생한 것보다 조금 늦게 처리됩니다.

이벤트 루프에서는 SocketSet을 원하는 이벤트가있는 소켓으로 채 웁니다. 소켓에서 새로운 수신 데이터를 수신하려면 "읽을 수있는"세트로 이동하십시오. 전송할 데이터가 있으면 소켓은 "쓰기 가능"세트에 있어야합니다. 그리고 모든 소켓은 "오류"세트에 있어야합니다.

select은 이벤트가 들어올 때까지 (잠자기) 차단하고 실행 가능한 이벤트가있는 소켓으로 SocketSet을 채 웁니다. 그런 다음 응용 프로그램은 읽을 수있는 소켓에 대한 데이터를 받고, 쓰기 가능한 소켓에 대한 대기중인 데이터를 보내고, 오류가 발생한 소켓에 대한 정리를 수행하여 적절하게 응답 할 수 있습니다.

다음은 광섬유가 아닌 이벤트 기반 네트워킹의 구현입니다 (ae.net.asockets).

+0

감사합니다. 이것은 정확히 내가 찾던 답변 유형입니다! – Bauss