2017-01-04 1 views
18

Mono 3.12에서 요청 기반 스트리밍 프로토콜을 구현하기 위해 Socket을 사용하여 Socket.SendAsync(SocketAsyncEventArgs)을 사용하고 있습니다. 여러 데이터 버퍼를 설정하려면 SocketAsyncEventArgs.BufferList을 사용하고 있습니다. SocketSocketAsyncEventArgs에 대한 문서에서 BufferList의 모든 바이트를 전송하지 않고도 TCP 소켓 SendAsync 작업을 완료 할 수 있습니까?

, 나는 BufferList를 사용하는 경우 모든 바이트가 우리가 SocketAsyncEventArgs.BytesTransferred에 대해 검증 할 필요가 인상을 떠나 보내지 않고 SocketAsyncEventArgs.Completed 제기 할 수 있는지 여부에 대한 언급을 찾을 수 없습니다. 한편

Socket.BeginSend는 응용 프로그램이 BeginSend를 호출하면 보장

, 시스템은 지정된 콜백 메서드를 실행하는 별도의 스레드를 사용하는 것을 만들고, 할 Socket까지 EndSend에 블록 요청한 바이트 수를 보내거나 예외를 throw합니다.

은 사양은 SocketAsyncEventArgs.BufferListSendAsync를 사용하는 경우 전송 된 바이트의 수에 대해 어떻게 보증을합니까?

이벤트가 SocketError.Success으로 완료되었다고 가정합니다.

+1

"소켓 오류없이 'SocketAsyncEventArgs.Completed' 핸들러를 호출 할 수 있습니까?'e.BytesTransferred! = length'?" .NET Framework에서 수집 할 수없는 것은 http://stackoverflow.com/questions/28675811/when-i-call-wsasend-will-all-the-data-be-sent와 http : // stackoverflow입니다. .com/questions/14347708/calling-wsasend-in-completion-port – jorgebg

+0

테스트 용 코드를 제공 할 수 있습니까? –

+0

@DieterMeemken 답변을 테스트하기 위해 무엇을 테스트해야합니까? 사양이 어떻게 보장합니까? 필자가 언급했듯이,'SendAsync'와'BufferList'를 가진'SocketAsyncEventArgs'를 사용하고 있습니다. –

답변

1

SocketAsyncEventArgs.BufferList과 함께 SendAsync를 사용할 때 사양에 따라 전송되는 바이트 수가 보장됩니까?

오류가 발생하면 이벤트가 발생하여 모든 바이트가 전송되지 않았다고 가정 할 수 있습니다. 이를 위해서는 SocketError.Success에 대한 SocketAsyncEventArgs.SocketError를 테스트해야합니다. 또한 '사양'을 참조하는 경우 SendAsync 및 기타 설명에 대해 링크 한 이후로 (Microsoft) Windows 소켓 문서를 의미한다고 가정합니다.

성공한 경우 Completed 이벤트가 호출 될 때 문서에서 말하는 내용을 확인하거나 전송 된 바이트 수를 나타내려면 몇 단계를 거쳐야합니다. 첫 번째 단계는 SendAsync가 중복 된 I/O를 사용하는지 확인하는 것입니다. 이 질문에 대한 대답은 Overlapped Input/Output 문서에 나와 있습니다. 이 메커니즘의 구현은 기본 전송 공급자에게 필수적이므로 Windows 소켓에서 사용할 수 있도록 보장되는 유일한 겹쳐진 I/O 메커니즘입니다. 따라서 SendAsync는 WSA_FLAG_OVERLAPPED 특성을 가진 소켓을 사용하도록 보장됩니다.

SendAsync reference implementation을 검사 한 결과 실제로 SendAsync가 중복 된 I/O가있는 WSASend를 사용하고 있지만 이는 단지 관찰 일뿐입니다.

두 번째 단계는 중복 된 I/O가 전송 된 바이트의 양과 관련된 완료 이벤트의 신호에 대해 알려주는지 확인하는 것입니다. 이 상황은 여러 곳에서 설명됩니다 (예 : Overlapped I/I and Event Objects 페이지). '송신 버퍼 사용시 표시가 제공됩니다'. [WSASend] 함수에 대한 설명 부분에서 좀 더 자세히 설명합니다 : '버퍼가 전송에 의해 소비 된 경우 이벤트 객체의 루틴 또는 설정 완료를 완료하는 완료 표시가 발생합니다. .

이 문구의 정확한 해석을위한 여지가 남아 있습니다.기본적으로 데이터는 소켓 범위 밖의 기본 전송 메커니즘에 의해 받아 들여지고 확인되었다고합니다. 이것이 반드시 원격 종점 프로토콜 계층에 도착했다는 것을 의미하지는 않습니다. 이것은 통신 프로토콜에 따라 달라집니다. TCP 스트리밍 소켓의 경우 데이터가 원격 끝점에 도착했음을 나타냅니다.

여기서 결론은 문서가 모든 바이트가 전송 된 시점에서만 SendAsync completed 이벤트가 발생한다는 것을 보장합니다 (오류가없는 상황에 대해).

+0

예,'SocketError.Success' 만 가정 해 봅시다. 내 질문을 수정하겠습니다. 나는 확신하지 못한다. 문서에 링크 할 때, 의도는 .NET 표준 라이브러리에 링크하는 것입니다.이 라이브러리는 Windows뿐 아니라 모든 .Net 런타임에서 구현해야합니다. Windows 구현은 한 가지 방법 일 뿐이므로 올바른 방법일까요? –

-1

여기에서 무엇을 확인 하시겠습니까? 모든 바이트를 보낼 때 모든 바이트를받지 못하는 이유에 대해 우려하십니까?

한 번에 100 바이트를 보내고 다른 끝에서 100 바이트를 읽으려는 경우 한 번에 모든 바이트를 수신한다고 보장 할 수 없습니다. 1 바이트의 100 패킷으로 나눌 수 있습니다. 그것이 TCP가 작동하는 방식입니다. 항상 바이트를 축적 한 다음 패킷을 형성하고 분리해야합니다. 이를 TCP 소켓 배관 작업이라고합니다. WCF와 모든 래퍼가 당신을 위해 그것을합니다.

관련 문제