nonblocking listner

ㅋㅋ·2022년 10월 29일

csharp게임서버

목록 보기
6/16
  • initialize
public void Init(IPEndPoint endPoint, Func<Session> sessionFactory)
{
    _listenSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
    _sessionFactory += sessionFactory;

    _listenSocket.Bind(endPoint);
    _listenSocket.Listen(10);

    SocketAsyncEventArgs args = new SocketAsyncEventArgs();
    args.Completed += new EventHandler<SocketAsyncEventArgs>(OnAcceptCompleted);
    RegisterAccept(args);
}

세션을 상속받아 컨텐츠 세션을 만들어 사용하는 경우

어떤 세션을 만들지 정하는 함수를 받아 클라이언트가 접속 시 해당 함수로 생성한다.

SocketAsyncEventArgs는 async 이벤트 시 인자로 넘겨지며 계속 사용됨

args.Completed에 accept 시 발생시킬 콜백 함수를 등록

RegisterAccept 함수로 accept 진행


  • register
void RegisterAccept(SocketAsyncEventArgs args)
{
    args.AcceptSocket = null;

    bool pending = _listenSocket.AcceptAsync(args);
    if (pending == false) // 대기 없이 바로 실행된 경우
    {
        OnAcceptCompleted(null, args);
    }
}

args가 이전에 발생한 소켓을 들고 있을 수도 있기 때문에 AcceptSocket을 초기화

_listenSocket.AcceptAsync(args) 함수를 통해 accept를 비동기적으로 실행시킴

pending을 통해 해당 함수가 즉각적으로 실행됐는지 알 수 있는데,

즉각적으로 실행됐으면 Completed에 등록했던 이벤트가 발생하지 않기 때문에

콜백 함수를 직접 호출해야 함


  • complete
void OnAcceptCompleted(object sender, SocketAsyncEventArgs args)
{
    if (args.SocketError == SocketError.Success)
    {
        Session session = _sessionFactory.Invoke();
        session.Start(args.AcceptSocket);
        session.OnConnected(args.AcceptSocket.RemoteEndPoint);
    }
    else
    {
        Console.WriteLine(args.SocketError);
    }

    RegisterAccept(args);
}

세션을 생성하고 클라이언트 소켓을 전달

그 후 다른 클라이언트를 받기 위해서는

register를 다시 불러 AcceptAsync를 또 실행해야 함

0개의 댓글