식당으로 비유? (Receive, Send와 Asynchronization)
366
작성한 질문수 50
나름대로 식당 예시로 비유를 해봤는데요, 제가 정확히 이해한게 맞는지 확인해보고자 질문을 남깁니다.
ReceiveAsync가 비동기로 처리되는 상황 : 대기 손님이 없는 경우. 일단 아무나 입장할 수 있도록 준비를 해둔 상태이고, 손님이 등장하면 바로 입장시킴. (`e.Completed` 호출)
ReceiveAsync가 동기로 처리되는 상황 : 대기 손님이 있는(많은) 경우. 그냥 존재하는 손님을 바로 입장시킬 수 있음.
SendAsync가 비동기로 처리되는 상황 : 음식을 3개 시킨 손님이 있다. 첫 번째 음식 `A`가 나왔는데, 손님이 아직 테이블로 가져가지 못한 경우이다. 손님이 아직 테이블로 음식을 가져가지 못했다고 해서, `A`를 가져갈 때 까지 두 번째 음식 `B`를 내보내지 않고 기다릴 이유가 없으므로 `B`를 카운터에 놓여있는 `A`의 옆에 둔다. (_sendQueue에 Enqueue한다.)
SendAsync가 동기로 처리되는 상황 : 음식을 3개 시킨 손님이 음식 `A`가 나온 즉시 곧바로 테이블로 가져가는 데 성공한 경우이다.
감사합니다.
답변 1
7
Recv는 맞는데 Send는 좀 얘기가 다릅니다.
이 부분은 비유하기 보다는 그냥 직빵으로 원리를 이해하는게 더 편할 수도 있는데요.
소켓을 만들면, 내부적으로 커널 레벨에
[수신버퍼(RecvBuffer)][송신버퍼(SendBuffer)] 짝이 만들어집니다.
우리가 서버 코드에서 Send를 요청할 때
커널 송신버퍼에 데이터를 복사하면 성공으로 간주합니다.
그 다음 운영체제가 이를 상대 컴퓨터에 보내는 것을 처리할테고,
이 데이터는 상대방의 커널 수신버퍼에 들어가게 됩니다.
반대로 우리가 Recv를 호출하면,
커널 수신버퍼에 있는 데이터를 유저레벨로 복사하는데
데이터가 1바이트라도 있으면 성공, 아니면 실패한 상황이 됩니다.
결국 나와 상대방의 상황이 맞물려 있는데
상대방이 재빨리 데이터를 Recv해서 상대 수신버퍼를 비워주지 않으면,
우리의 송신버퍼를 비울 수가 없게 됩니다.
결국 Send가 바로 완료되는 조건은, [커널 송신버퍼에 데이터를 복사할 수 있는 경우]이고
그럴 수 없다면 커널 송신버퍼가 비워질때까지 대기하면서
한참 후에 완료됩니다. 그리고 이 때 완료 통지가 콜백 함수로 호출됩니다.
Recv는 거꾸로 [커널 수신버퍼에 데이터가 1바이트라도 있는 경우] 바로 완료되고,
그렇지 않다면 수신버퍼에 데이터가 채워지기 전까지 완료되지 않습니다.
C#에서의 RAII
0
63
3
TLS 질문드립니다.
0
79
2
SpinLock과 컨텍스트스위칭에 대해 질문 남겨요.
0
74
2
Unity Span
0
97
2
XML, Dll 차이점
0
134
2
Session 질문입니다
0
95
1
Write Read 커서 키워드
0
87
1
더미 클라이언트 수에 따른 OnDisconnect 발생
0
85
2
네트워크 Send 전담 스레드 배치
0
111
2
UnhandledException 으로 서버 터지는 경우
0
102
2
컨텐츠 단, 엔진 단
0
118
1
질문 있습니다
0
92
2
C# 게임서버 3D MMORPG
0
159
2
유니티6 버전
0
104
2
receive하는 부분과 send하는 부분의 차이
0
152
2
커서의 위치의 중요성
0
110
2
C++ 전혀 모르는데 C# 서버
0
176
2
강의에 질문이 있습니다
0
92
2
멀티스레드 이해도 질문
0
106
1
500 vs 500
0
147
3
OnAcceptHandler 액션 함수
0
70
1
이 정도 서버의 객관적인 수준이 궁금합니다.
0
204
2
36. Serialization #3 에서 string (name) 코드 수정 질문
0
85
2
외부 컴퓨터와의 통신 방법이 궁금합니다
0
112
1





