본문 바로가기
cs공부/네트워크프로그래밍

네트워크 프로그래밍 -Send코드 개선하기

by 코딩하는 돼징 2023. 7. 13.
반응형

Send 코드 참조

 

네트워크 프로그래밍 - C# Non - blocking을 사용한 Server 소켓프로그래밍의 Send

Receive코드 알아보러 가기 네트워크 프로그래밍 - C# Non - blocking을 사용한 Server 소켓프로그래밍의 Receive Listener코드 알아보러 가기 네트워크프로그래밍 - C# 간단한 Non - blocking 사용한 Server 소켓프

code-piggy.tistory.com


1. BufferList사용하기

01 한번에 하나의 버퍼를 전송

void RegisterSend()
{
    _pending = true; // 다음에 Send되는애가 Register안돼고 바로 queue에 담겨지기 위해서
    byte[] buff = _sendQueue.Dequeue();
    _sendArgs.SetBuffer(buff, 0, buff.Length);
    bool pending = _socket.SendAsync(_sendArgs);
    if (pending == false)
        OnSendCompleted(null, _sendArgs);
}

02 여러 버퍼를 동시에 전송

List<ArraySegment<byte>> _pendingList = new List<ArraySegment<byte>>();
void RegisterSend()
{
    while (_sendQueue.Count>0)
    {
        byte[] buff = _sendQueue.Dequeue();
        _pendingList.Add(new ArraySegment<byte>(buff,0,buff.Length));
    }
    // BufferList에 예약된 목록들 다 넣기
    _sendArgs.BufferList = _pendlingList; 
    bool pending = _socket.SendAsync(_sendArgs);
    if (pending == false)
        OnSendCompleted(null, _sendArgs);
}

리스트를 따로 만들어서 BufferList에 넣는 이유

BufferList에는 List<ArraySegment<byte>>형식이 필요하기 때문이다.

_sendQueue에서 바로 BufferList에 할당하지 못한다. 그 이유는 _sendQueue가  List<ArraySegment<byte>>형식과 일치해야 하는데 _sendQueue의 형식은 byte[]이기 때문이다.

따라서 _sendQueue에서 버퍼를 꺼내어 ArraySegment<byte>변환한 후 이를 _pendingList에 추가하여List<ArraySegment<byte>>형식을 가진 _sendArgs.BufferList에 할당하는 것이다.


2. _pendingList사용하여 대기 확인하기

01 _pending사용

public void Send(byte[] sendBuff)
{
    lock (_lock)
    {
        _sendQueue.Enqueue(sendBuff);
        if (_pending == false) 
            RegisterSend();
    }
}

02 _pendligList 사용

public void Send(byte[] sendBuff)
{
    lock (_lock)
    {
        _sendQueue.Enqueue(sendBuff);
        if (_pendingList.Count == 0) // 대기 확인
            RegisterSend();
    }
}

01 _pending사용

if(_sendQueue.Count > 0)
{
    RegisterSend();
}
else
    _pending = false;

02 _pendingList사용

OnSendCompleted에서 예약한 _pendingList가 완료되었음을 의미하므로

_pendList.Clear한다.

try
{
    _sendArgs.BufferList = null;
    _pendingList.Clear();

    Console.WriteLine($"Transfoerred bytes : {_sendArgs.BytesTransferred}");
    if(_sendQueue.Count > 0)
    {
        RegisterSend();
    }
}

결과 화면


여러 버퍼를 동시에 전송에서 아직 부족한 점

동시다발적으로 패킷이 몰릴 때 

상대방이 악의적으로 아무 의미 없는 정보들을 계속 보낼 때

 

 

 

 

 

 

참고 :  본 내용은 MMORPG  PART4 강의를 수강하여 작성하였습니다.

https://www.inflearn.com/course/%EC%9C%A0%EB%8B%88%ED%8B%B0-mmorpg-%EA%B0%9C%EB%B0%9C-part4

 

반응형

댓글