버그 해결을 위한 모든 질문을 던져
0 votes
299 views

저의 목표는 가능한한 많은 연결을 유지할 수 있는 게임 서버를 만드는 것입니다.

많은 수의 동접자를 처리할 수 있도록 하고 싶기 때문입니다.

현재 저는 여러가지 방법을 사용하여 채팅 서버를 만들어봤습니다.

제가 시도해본 방법들은 다음과 같습니다.

(편의상 소켓이라고 표현하였지만 정확히는 TcpClient 클래스를 사용하였습니다)

 

1. 연결된 소켓별로 NetworkStream.Read()를 수행하는 쓰레드 생성해서 클라이언트를 관리하는 채팅 서버.

2. 연결된 소켓별로 NetworkStream.ReadAsync()를 수행하는 Task를 생성해서 클라이언트를 관리하는 채팅 서버.

(Read 및 ReadAsync는 While 루프 내부에서 수행됩니다)

 

사실 저는 이 방식이 직관적으로 느껴지고, 사용하는 데에도 아무런 문제가 없습니다.

하지만 이 방식이 '가능한한 많은 동접자 수를 처리할 수 있는 방식인가?'하는 의문이 듭니다.

더 나은 방법이 있을까요?

 

또 관련 정보를 찾기 위해 구글링을 하던 도중

"...예전처럼 소켓마다 쓰레드 생성해서 관리하던 시절에..."

위 문구가 들어간 글을 발견했습니다. 

소켓마다 쓰레드 생성해서 관리하는 방식이 예전 방식이라면, 

지금은 어떤 방식으로 Accept된 소켓들을 관리하나요?

구글링을 해봐도 관련 정보를 찾을 수 없어 이렇게 질문을 올립니다.

정말 알고싶습니다. 답변 부탁드립니다!

(추측성 답글 대신 경험자 분의 답변을 기다립니다!)

 

질문 정리

1. 가능한한 많은 동접자를 처리할 수 있는 소켓 관리 방법?

2. 소켓 별로 쓰레드를 생성하는 방식을 사용해서 서버를 만들어도 괜찮은지?

3. 만약 소켓 별로 쓰레드를 생성하는 방식이 최선의 해결책이 아니라면, 더 나은 대안은 무엇인지?

asked (27 point)
수정됨 , 299 views

2 answers

+1 vote
우수 답변

제가 c#으로 만든 서버가 있는데 참고하시면 좋을것 같네요.

https://github.com/sunduk/FreeNet

 

소켓당 스레드를 쓰는 방식은 메모리도 많이 먹고 쓰레드가 너무 많이 생겨버리게 되죠.

저는 닷넷 비동기 소켓을 활용하여 만들었습니다.

(c++로 치면 IOCP와 비슷하다고 보면 됩니다)

소스포지나 ms공식 개발 문서에도 나와 있는 방식이고 

테스트 결과 소켓당 스레드나 TcpClient를 쓰는것보다 성능이 훨씬 좋았습니다.

단, 몇년전에 만든거라 요즘에는 어떤 기술을 쓰는지 모르겠습니다.

 

answered (82 point)
선택됨
콜백 방식으로 구현을 하셨네요. 좋은 참고가 되었습니다. 답변 감사합니다!
그런데 성능 테스트는 어떤 방식으로 하셨나요?
테스트 클라이언트를 이용하여 일정 크기의 패킷을 마구 보내는 방식으로 했습니다.

초당 10번 혹은 20번씩 일정시간 패킷을 마구 쏘게 한 뒤 응답시간과 메모리 사용량, CPU점유율등을 측정했죠.

툴은 어떤걸 쓰셔도 상관 없지만, 제 github에 가면 테스트 방법과 툴이 있으니 그걸 참고하셔도 될것 같네요.
그렇군요. 답변 감사드립니다!
+1 vote
C# 에서 성능을 위한 소켓 컨트롤 방법은 단 하나.  SocketAsyncEventArgs 를 이용하는 것입니다.

비동기 소켓들은 받은 패킷을 큐잉만하고 수신대기 반복.

스레드 1개가 주기적으로 swap, 디큐해서 처리합니다.
answered (163 point)
시도해볼만한 가치가 있는 것 같습니다. 귀중한 지식을 공유해주셔서 감사합니다!

버그 해결을 위해 도움을 구하고, 도움을 주세요. 우리는 그렇게 발전합니다.

throw bug 는 프로그래밍에 대한 전분야를 다룹니다. 질문,논의거리,팁,정보공유 모든 것이 가능합니다. 프로그래밍과 관련이 없는 내용은 환영받지 못합니다.

430 질문
564 answers
572 댓글
37,579 users