본문 바로가기

게임서버(Game Server)

[게임서버] AcceptEx와 ConnectEx-IOCP

 

프로젝트 정보(Project Informaion)

사진 및 프로젝트 설명

프로젝트는 Server, Clinet 이렇게 두 개의 프로젝트가 있다.

Server: Server.cpp, Server.h

Clinet: Iocp_CIocp_Client.cpp, Server.h(Server의 헤더 파일을 공유한다.)

최대 접속 클라이언트는 50명까지 이며  그 이후는 서버에서 받지 않는다. 클라이언트에서는 계속 요청을 한다.

서버와 클라이언트를 켜면 클라이언트에서 서버에게 Connect를 요청하고 서버는 그 요청을 Accpet 하고 리모트 정보를

받아 IP와 Port를 출력하고 클라이언트에게 서버가 가지고 있는 ID값을 "HELLO WORLD"와 함께 보낸다.

 

============Server============

  • Iocp Class

HANNDLE ioHandle_ IOCP 핸들
SOCKET listenSocket_ AccpetEx()에 들어갈 listen socket
std::mutex lock_ 사용 X
std::atomic<int> userId_ Client 관리용 ID

IOCP HANDLE을 포함해서 필요한 것들을 묶어놓은 Iocp class이다.

 

  • Server WorkThread

서버는 Accept를 받으면 IOCP에서 접속을 처리하며 OVERLAPPED을 통해 넘어온 Socket을 서버가 관리하는

구조체 배열에 넣는다. 이때 전역 변수 g_iocp.userid 는 atomic <int>로 여러 스레드에서 이 변수에 접근해도

데이터 레이스가 발생하지 않는다.

 

============Client============

  • Client workThread

Conect 또한 IOCP에서 처리 후 다시 Connect 함수를 호출한다.

 

  • Client WaitForSingleObject

CoonectEx는 비동기 함수이기 때문에 연결 여부를 판단할 수가 없다. 그래서 WaitForSingObject() 함수를 사용해서

3초 정도를 기다린다. WAIT_FAILED 상태이면 서버가 켜져있지 않거나 문제가 생긴 경우이다.

 

 

후기

처음으로 AccpetEx와 ConetEx를 IOCP와 연결해서 사용해보았다. 이전까지는 IOCP를 사용해도 Accpet를 받을 때

accpet() 동기 함수를 사용했기 때문에 따로 스레드를 만들어 주었다.  사실 네트워크를 탄게 아니라서 어느 잠재적 문제가 있을지 알 수 없지만 사용 및 적용해보는 게 목표였기 때문에 달성했다고 생각한다.

다음에는 Disconect를 사용해서 소켓을 Close 하는 게 아닌 재사용할 수 있는 Socket pool을 적용해볼 예정이다.

 

유의사항

* 최대 허용량 클라이언트는 50개입니다.

* 해당 프로젝트는 예외 처리를 최소한으로 했기 때문에 버그가 있을 수 있습니다.

* Clinet는 Server의 헤더 파일을 공유합니다.

* 기본 루프 백(127. 0. 0. 1) 과 PORT(9000)이며 네트워크를 통한 테스트는 진행하지 않았습니다.

*  TCP환경에서 발생할 수 있는 패킷수신은 고려하지 않고 진행했습니다.

* 만약 이 블로그 글을 보고 잘못된 점이나 참고 가능한 것 등 공부가 가능한 게 있다면 댓글이나

   메일(SnowFleur0128@gmail.com) 로 보내주시면 감사하겠습니다.

 

출처 및 소스코드 링크

git: www.github.com/SnowFleur/2020-Server/tree/master/IOCP-AcceptEx%2CConnectEx

관련 글

[게임서버(Game Server)] - [게임 서버] AcceptEx와 ConnectEx

 

20.05.29

사진 수정 및 유의사항 추가