namespace SeverCore
{
internal class Session
{
// 보낼것들을 큐에 담아둔다.
Queue<byte[]> _sendQueue = new Queue<byte[]>();
List<ArraySegment<byte>> _pendingList = new List<ArraySegment<byte>>();
SocketAsyncEventArgs _sendArgs = new SocketAsyncEventArgs();
public void Send(byte[] sendBuff)
{
lock (_lock)
{
_sendQueue.Enqueue(sendBuff);
// 첫빠따인 경우
if (_pendingList.Count == 0)
RegisterSend();
}
}
pendingList가 비어있는 경우 바로 등록함수를 실시한다.
void RegisterSend()
{
while (_sendQueue.Count > 0)
{
byte[] buff = _sendQueue.Dequeue();
_pendingList.Add(new ArraySegment<byte>(buff, 0, buff.Length));
}
_sendArgs.BufferList = _pendingList;
bool pending = _socket.SendAsync(_sendArgs);
if (pending == false)
OnSendCompleted(null, _sendArgs);
}
Queue에 있는 buff들을 _pendingList에 넣어준다.
이후 해당 List를 _sendArgs.BufferList에 넣어서 사용한다.
void OnSendCompleted(object sender, SocketAsyncEventArgs args)
{
lock (_lock)
{
if (args.BytesTransferred > 0 && args.SocketError == SocketError.Success)
{
try
{
_sendArgs.BufferList = null;
_pendingList.Clear();
Console.WriteLine($"Transferred bytes: {_sendArgs.BytesTransferred}");
if (_sendQueue.Count > 0)
RegisterSend();
}
catch (Exception e)
{
Console.WriteLine($"OnSendCompleted Failed {e}");
}
}
else
{
Disconnect();
}
}
}
다 보내고 나면 BufferList를 null로 설정하고 _pendingList를 비워준다.