관리 메뉴

有希

Session#1 본문

프로그래밍/C# 게임서버

Session#1

有希. 2021. 9. 9. 14:17

Connect, Disconnect를 비동기로 하였으니 이제 receive, send를 비동기로 만들 차례이다.

Async를 사용하여 args를 넣어주게 되면 스레드 풀에서 스레드 하나를 데려와서 주 스레드말고 다른 스레드에게 일을 시킨다.

Session은 다음과 같은 역할(함수)를 가진다.

Start(시작)

Send(송신)

RegisterRecv(수신)

OnRecvCompleted(수신 완료시)

Disconnect(연결 끊기)

송신은 하난데, 수신이 2개인 이유가 지금은 수신만 비동기로 만들어서 수신만 2개로 쪼개졌다.

비동기로 만드려고 한다면 비동기를 호출하는 부분과, 호출이 완료됐을 때 함수가 따로 존재해야 한다. 이렇게 해야 비동기로 작업이 완료됐을 때 따로 완료시행동 함수만 호출가능하다.

우선, Session 클래스를 별도 파일로 생성하고 Socket _socket을 선언한다.

소켓을 따로 두는 이유는 _socket과의 연결을 유지할 Session이니까.(말이 조금 이상하게 써졌다)

Start는 Listener와 마찬가지로 한다. accept를 받아주는 부분처럼 처음 비동기 호출 함수(RegisterRecv), 완료시 행동 함수(OnRecvCompleted) 생성해준다.

1. recvArgs를 SocketArgsEventArgs로 생성하고,

2.Recv완료 시 행동할 함수를 delegate에 등록시켜준다.

3. 그 후, recv시 받아줄 버퍼를 recvArgs.SetBuffer(buffer, offset, size) 로 설정해준다.

4. RegisterRecv 함수 호출

Send

그냥 byte[] 받아서 _socket.Send 해준다

Recv

RegisterRecv에서는 비동기로 받을 준비만 해준다.

recvArgs를 _socket.ReceiveAsync로 넘긴 뒤, pending으로 반환값을 받는다.

이전 처럼 false이면 즉시 completed 함수 실행, 아니라면 알아서 delegate로 등록해둔 Event객체가 실행해준다.

OnRecvCompleted에서는 recvArgs.BytesTransferred와 recvArgs.SocketError를 이용해서 정상적으로 받았는지 체크를 해준뒤, 정상이라면 데이터를 string으로 변환해서(여기선 string쓰기로 약속했다고 가정, 프로젝트 별로 약속해서 byte[]를 맞게 변환해야 한다.) 출력해준다.

Disconnect

연결된 소켓과 끊겼는지를 확인하는 int값을 전역으로 하나 둔다. 내가 이 값을 끊지 않았다고 생각해서 끊으려는 도중, 다른 빠른 녀석이 들어와서 끊었다고 값을 바꾸고 먼저 끊는 함수를 실행해버리면 나는 2중으로 끊어버리기 때문에 에러가 난다. 그래서 이 부분을 Interlocked를 사용해줘야한다.

1. Interlocked.Exchange로 끊긴 상태인지 확인. 내가 확인중이라면 나보다 빠른 녀석은 나를 지나쳐가는 것이 아닌 내 뒤에서 대기

2. 끊기지 않았다면 끊긴 상태로 변경하고, Shutdown 및 close. 끊긴 상태라면 그대로 return

 

'프로그래밍 > C# 게임서버' 카테고리의 다른 글

Session#3  (0) 2021.09.09
Session#2  (0) 2021.09.09
소켓 프로그래밍 - 비동기 연결  (0) 2021.09.09
소켓 프로그래밍 기초  (0) 2021.09.07
통신 모델  (0) 2021.09.07