C#/네트워크

[c#][서버] Connector

goliot 2024. 6. 7. 13:41
반응형

Dummy Client 

  • 우선 서버코어에서, 클라이언트의 연결을 담당해줄 클래스를 구현해본다
class Connector
{
    Func<Session> _sessionFactory;
    public void Connect(IPEndPoint endPoint, Func<Session> sessionFactory)
    {
        Socket socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
        _sessionFactory = sessionFactory;

        SocketAsyncEventArgs args = new SocketAsyncEventArgs();
        args.Completed += OnConnectCompleted;
        args.RemoteEndPoint = endPoint;
        args.UserToken = socket;

        RegisterConnect(args);
    }

    void RegisterConnect(SocketAsyncEventArgs args)
    {
        //커넥션이 여러개 있을 수 있으니 로컬변수로 사용
        Socket socket = args.UserToken as Socket;
        if (socket == null) 
            return;
        
        bool pending = socket.ConnectAsync(args);
        if (pending == false)
            OnConnectCompleted(null, args);
    }

    void OnConnectCompleted(object sender, SocketAsyncEventArgs args)
    {
        if(args.SocketError == SocketError.Success)
        {
            Session session = _sessionFactory.Invoke();
            session.Start(args.ConnectSocket);
            session.OnConnected(args.RemoteEndPoint);
        }
        else
        {
            Console.WriteLine($"OnConnectCompleted Fail: {args.SocketError}");
        }
    }
}
  • Listener와 거의 대칭적으로 만들어졌다.
  • Dummy Client에서도 이제 Session을 사용해서 블록함수를 대체하자
class GameSession : Session
{
    public override void OnConnected(EndPoint endPoint)
    {
        Console.WriteLine($"OnConnected : {endPoint}");

        //보낸다
        for (int i = 0; i < 5; i++)
        {
            byte[] sendBuff = Encoding.UTF8.GetBytes($"Hello world! {i}");
            Send(sendBuff);
        }
    }

    public override void OnDisConnected(EndPoint endPoint)
    {
        Console.WriteLine($"OnDisConnected : {endPoint}");
    }

    public override void OnRecv(ArraySegment<byte> buffer)
    {
        string recvData = Encoding.UTF8.GetString(buffer.Array, buffer.Offset, buffer.Count);
        Console.WriteLine($"[From Server] {recvData}");
    }

    public override void OnSend(int numOfBytes)
    {
        Console.WriteLine($"Transferrd bytes: {numOfBytes}");
    }
}

class Program
{
    static void Main(string[] args)
    {
        //DNS 사용
        string host = Dns.GetHostName(); //내 로컬 컴퓨터의 호스트 이름
        IPHostEntry ipHost = Dns.GetHostEntry(host);
        IPAddress ipAddr = ipHost.AddressList[0];
        IPEndPoint endPoint = new IPEndPoint(ipAddr, 7777); //주소, 포트번호

        Connector connector = new Connector();
        connector.Connect(endPoint, () => { return new GameSession(); });

        while (true)
        {
            try
            {

            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }

            Thread.Sleep(100);
        }
    }
}
반응형

'C# > 네트워크' 카테고리의 다른 글

[c#][서버] RecvBuffer, SendBuffer  (1) 2024.06.07
[c#][서버] TCP vs UDP  (0) 2024.06.07
[c#][서버] Session  (1) 2024.06.06
[c#][서버] Listener  (0) 2024.06.05
[c#][서버] 소켓 프로그래밍  (0) 2024.06.05