많은 소켓에서 데이터를 송수신하는 소프트웨어를 개발 중입니다. 그것은 매우 비동기 적이며 그 이유 때문에 다음과 같은 시나리오가 걱정됩니다. N 개의 스레드가 동일한 소켓에 데이터를 보내려고합니다. 이것은 BeginSend를 동시에 호출하는 N 개의 스레드입니다.소켓 비동기 데이터 송수신
명확화 : 스레드를 사용하지 않지만 '시스템'이 사용합니다. "응용 프로그램이 BeginSend를 호출하면 시스템이 별도의 스레드를 사용하여 지정된 콜백 메서드를 실행합니다."
SocketException과 함께 실패했는지 확인하기 위해이 테스트를 수행했습니다. 아닙니다. (그에 대한 문서를 찾을 수 없기 때문에) 아니요 :
[Test]
public void DoIt2()
{
var byteCount = 0;
var manualEvents = new[] { new ManualResetEvent(false), new ManualResetEvent(false), new ManualResetEvent(false) };
var message = new byte[] { 0x01, 0x02, 0x03, 0x04 };
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
var callback = new AsyncCallback(ar =>{
var resetEvent = (ManualResetEvent)ar.AsyncState;
Interlocked.Add(ref byteCount, socket.EndSend(ar));
resetEvent.Set();
});
socket.Connect("127.0.0.1", 8000);
socket.BeginSend(message, 0, message.Length, SocketFlags.None, callback, manualEvents[0]);
socket.BeginSend(message, 0, message.Length, SocketFlags.None, callback, manualEvents[1]);
socket.BeginSend(message, 0, message.Length, SocketFlags.None, callback, manualEvents[2]);
WaitHandle.WaitAll(manualEvents);
socket.Close();
Assert.AreEqual(12, byteCount);
}
녹색이되었습니다. 그러나, 뭔가 잘못되었다는 것을 알아야합니다. EndSend/EndReceive가 호출되기 전에 BeginSend/BeginReceive를 여러 번 호출 할 수 있다고 가정하는 것이 안전합니까? 내 말은, 다음과 같은 패턴이 오케이 야?
- BeginSend
- BeginSend
- BeginSend
- EndSend 무엇 도착 데이터 순서에 대한
- EndSend
- EndSend
? 나는 이것이 TCP라는 것을 알고 있지만 나의 질문은 BeginSend가 비동기 적이기 때문에 1에서 보낸 데이터는 2와 3 전에 도착할 것인가?
감사합니다.
요점은 스레드를 사용하지 않지만 '시스템'이 사용한다는 것입니다. 그 문서는 "응용 프로그램이 BeginSend를 호출 할 때 시스템은 별도의 스레드를 사용하여 지정된 콜백 메소드를 실행합니다"라고 말합니다. 나는 '시스템'이 OS라고 가정한다. 나는 그 질문을 분명히하도록 업데이트 할 것이다. 고마워요 – lontivero
사과드립니다. 나는 .NET 클래스가 당신이하고있는 일을 감싸는 wrapper라면, 당신이 보낸 순서대로 OS가 그것을 할 것이라는 것을 안다. OS는 각 전송 요청마다 다른 스레드를 사용하지 않습니다. – noz
설명 해석하기 수업이 OS 레벨에서 IO 완성을 사용하고 있다고 생각됩니다. 이 말은 콜백이 BeginSend를 호출 한 스레드와 다른 스레드에서 발생한다는 것입니다. 그러나 추가 스레드가 하나만 포함되어 있습니다. 콜백이 스레드 안전 인 한 모든 것이 잘되어야합니다. – noz