네트워크 코어

정선호·2025년 2월 16일
0

Server

목록 보기
1/2

네트워크 코어는 TCP/IP 네트워크를 연결하고, 연결한 네트워크를 통해 주고받을 패킷의 처리 방식에 대한 코어 시스템을 구현해놓은 라이브러리이다.

서버뿐 아니라 클라이언트의 네트워크 연결 또한 네트워크 코어 라이브러리를 이용한다.

구조

각각 다음 클래스들로 나뉘어져 있다.

  • Listener : 서버가 사용하는 소켓 생성 및 연결 클래스
  • Connector : 클라이언트가 사용하는 소켓 생성 및 연결 클래스
  • RecvBuffer : 리스너와 커넥터가 받은 패킷들을 저장해두는 버퍼 클래스
  • Session : 패킷을 송수신받고 네트워크 상태에 따라 수행할 함수들을 모아놓은 클래스

Listener

서버에서 사용하는 소켓 연결 클래스이다. 다량의 클라이언트와 동시에 연결해야 하므로 많은 소켓을 열어둔다.
하나의 클라이언트에 연결이 성공했을 시 그 클라이언트에 대응되는 세션을 하나 만들어 할당해준다.

스도코드

클래스 Listener
{
    멤버 변수:
        - _lock: 멀티스레드 동기화를 위한 객체
        - _listenSocket: 클라이언트 연결을 수락할 소켓
        - _sessionFactory: 세션을 생성하는 함수
        - _acceptArgs: 비동기 연결 수락을 위한 SocketAsyncEventArgs 객체

    메서드:
        - Start(IPEndPoint endPoint, Func<Session> sessionFactory):
            - _sessionFactory를 설정
            - _listenSocket을 생성 및 바인딩하여 대기 상태로 설정
            - RegisterAccept()를 호출하여 클라이언트 연결을 수락

        - RegisterAccept():
            - _acceptArgs를 초기화하고 비동기 Accept 시도
            - Accept가 즉시 완료되면 OnAcceptCompleted 실행

        - OnAcceptCompleted(object sender, SocketAsyncEventArgs args):
            - 연결이 성공하면:
                - 세션 객체를 생성하고 Start 호출
                - RegisterAccept()를 다시 호출하여 다음 클라이언트 대기
            - 실패 시 RegisterAccept()를 다시 호출하여 대기

        - Stop():
            - _listenSocket이 존재하면 닫고 정리
}

Connector

클라이언트에서 사용하는 소켓 연결 클래스이다. 서버 하나와만 통신하므로 하나의 소켓을 열어둔다.
서버와의 연결을 성공하면 서버 세션을 하나 만들어 할당해준다.

스도코드

클래스 Connector
{
    멤버 변수:
        - _sessionFactory: 세션을 생성하는 함수

    메서드:
        - Connect(IPEndPoint endPoint, Func<Session> sessionFactory, int count = 1):
            - count 만큼 반복하여 소켓을 생성하고 연결 시도
            - RegisterConnect()를 호출하여 비동기 연결 요청

        - RegisterConnect(SocketAsyncEventArgs args):
            - 비동기 연결 요청 수행
            - 요청이 즉시 완료되면 OnConnectCompleted 실행

        - OnConnectCompleted(object sender, SocketAsyncEventArgs args):
            - 연결이 성공하면:
                - 세션을 생성하고 Start 호출
                - OnConnected 실행
            - 실패 시 오류 출력
}

RecvBuffer

서버와 클라이언트에서 주고받는 패킷들을 처리하기 전에 임시로 저장해두는 버퍼 클래스.
바이트 배열 형식의 버퍼와 이를 읽고 쓰는데 도움을 주는 유틸리티 함수들로 되어 있다.

스도코드

클래스 RecvBuffer
{
    멤버 변수:
        - _buffer: 데이터 저장용 버퍼 (ArraySegment<byte>)
        - _readPos: 읽기 위치 커서
        - _writePos: 쓰기 위치 커서

    속성:
        - DataSize: 현재 버퍼에 저장된 데이터 크기
        - FreeSize: 버퍼에 남은 공간 크기
        - ReadSegment: 현재 읽을 수 있는 데이터 범위 (ArraySegment<byte>)
        - WriteSegment: 데이터를 받을 수 있는 범위 (ArraySegment<byte>)

    메서드:
        - RecvBuffer(int bufferSize):
            - 버퍼를 bufferSize 크기로 초기화

        - Clean():
            - 데이터가 없으면 커서를 초기화
            - 데이터가 남아 있으면 앞으로 이동하여 정리

        - OnRead(int numOfBytes):
            - numOfBytes만큼 읽기 커서를 이동
            - 유효성 검사 후 성공 여부 반환

        - OnWrite(int numOfBytes):
            - numOfBytes만큼 쓰기 커서를 이동
            - 유효성 검사 후 성공 여부 반환
}

Session

세션 클래스는 네트워크에 연결되어 있는 각 객체들의 상태를 저장 및 변경하는 클래스이다.

스도코드

클래스 Session (추상 클래스)
{
    멤버 변수:
        - _socket: 연결된 클라이언트 소켓
        - _disconnected: 연결 상태를 나타내는 플래그
        - _lock: 멀티스레드 동기화를 위한 객체

        - _sendQueue: 전송할 데이터를 저장하는 큐
        - _pendingList: 현재 전송 중인 데이터 리스트
        - _sendArgs: 비동기 전송을 위한 SocketAsyncEventArgs

        - _recvArgs: 비동기 수신을 위한 SocketAsyncEventArgs
        - _recvBuffer: 수신 데이터를 저장할 RecvBuffer 객체

    #region 가상 함수들
        - OnConnected(EndPoint endPoint): 클라이언트가 연결될 때 호출되는 함수
        - OnRecv(ArraySegment<byte> buffer): 데이터를 받을 때 실행되는 함수 (리턴값: 처리한 데이터 크기)
        - OnSend(int numOfBytes): 데이터를 성공적으로 전송했을 때 호출되는 함수
        - OnDisconnected(EndPoint endPoint): 클라이언트 연결이 종료될 때 호출되는 함수
    #endregion

    메서드:
        - Clear():
            - _sendQueue와 _pendingList를 초기화

        - Start(Socket socket):
            - _socket 할당 및 이벤트 핸들러 등록
            - 수신 시작 (RegisterRecv 호출)

        - Send(List<ArraySegment<byte>> sendBuffList):
            - 데이터가 존재하지 않으면 반환
            - sendBuffList의 데이터를 _sendQueue에 추가
            - _pendingList가 비어 있다면 RegisterSend 호출

        - Send(ArraySegment<byte> sendBuff):
            - _sendQueue에 데이터 추가
            - _pendingList가 비어 있다면 RegisterSend 호출

        - Disconnect():
            - 이미 연결이 종료되었으면 반환
            - OnDisconnected 호출 후 소켓 종료
            - Clear() 실행하여 내부 데이터 정리

    #region 네트워크 통신
        - RegisterSend():
            - 연결이 종료되었으면 반환
            - _sendQueue에서 데이터를 꺼내 _pendingList에 추가
            - _sendArgs에 데이터 설정 후 비동기 전송 시도
            - 만약 전송이 즉시 완료되었다면 OnSendCompleted 실행

        - OnSendCompleted(object sender, SocketAsyncEventArgs args):
            - 전송이 성공하면:
                - _pendingList 초기화
                - OnSend 호출
                - _sendQueue에 남은 데이터가 있으면 RegisterSend 호출
            - 전송 실패 시 Disconnect 실행

        - RegisterRecv():
            - 연결이 종료되었으면 반환
            - _recvBuffer의 버퍼를 초기화하고 비동기 수신 요청
            - 요청이 즉시 완료되면 OnRecvCompleted 실행

        - OnRecvCompleted(object sender, SocketAsyncEventArgs args):
            - 데이터 수신이 성공하면:
                - _recvBuffer의 Write 커서를 이동
                - OnRecv을 호출하여 데이터를 처리한 크기를 받아옴
                - 데이터가 잘못 처리되었으면 Disconnect 실행
                - Read 커서를 이동한 후 RegisterRecv 재호출
            - 데이터 수신이 실패하면 Disconnect 실행
    #endregion
}
profile
학습한 내용을 빠르게 다시 찾기 위한 저장소

0개의 댓글

관련 채용 정보