현재까지 구현된 코드
// ServerCore
// Session.cs
class Session
{
    Socket _socket;
    int _disconnected = 0;
    Queue<byte[]> _sendQueue = new Queu<byte[]>();
    bool _pending = false;
    SocketAsyncEventArgs _sendArgs = new SocketAsyncEventArgs();
    SocketAsyncEventArgs _recvArgs = new SocketAsyncEventArgs();
    object _lock = new object();
    public void Start(Socket socket)
    {
        _socket = socket;
        SocketAsyncEventArgs _recvArgs = new SocketAsyncEventArgs();
        _recvArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnRecvComplete);
        _recvArgs.SetBuffer(new byte[1024], 0/*시작인덱스*/, 1024);
        _sendArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnSendCompleted);
        RegisterRecv();
    }
    public void Send(byte[] sendBuff)
    {
        lock(_lock)
        {
            _sendQueue.Enqueue(sendBuff);
            if(_pending == false)
                RegisterSend();
        }
    }
    public void Disconnect()
    {
        if(Interlocked.Exchange(ref _disconnected, 1) == 1)
            return;
        _socket.Shutdown(SocketShutdown.Both);
        _socket.Close();
    }
    void RegisterSend()
    {
        _pending = true;
        byte[] buff = _sendQueue.Dequeue();
        _sendArgs.SetBuffer(buff, 0, buff.Length);
        bool pending = _socket.SendAsync(_sendArgs));
            OnSendCompleted(null, _sendArgs);
    }
    void RegisterRecv()
    {
        bool pending = _socket.ReceiveAsync(_recvArgs);
        if(pending == false)
            OnRecvComplete(null, _recvArgs);
    }
    void OnRecvComplete(object sender, SocketAsyncEventArgs args)
    {
        if(args.BytesTransferred > 0 && args.SocketError ==SocketError.Success)
        {
            try{
                string recvData = Encoding.UTF8.GetString(args.Buffer, args.Offset, args.BytesTransferred);
                RegisterRecv();
            }
            catch()
            {
            }
        }
        else
        {
            Disconnect();
        }
    }
    void OnSendComplete(object sender, SocketAsyncEventArgs args)
    {
        lock(_lock)
        {
            if(args.BytesTransferred > 0 && args.SocketError ==SocketError.Success)
            {
                try{
                    // SendQueue안에 남아있는지 확인
                    if(_sendQueue.Count > 0)
                    {
                        RegisterSend();
                    }
                    else
                        _pending = false;
                }
                catch()
                {
                }
            }
            else
            {
                Disconnect();
            }
        }
    }
}
최적화가 필요한 부분이 있다
void RegisterSend()
{
    _pending = true;
    byte[] buff = _sendQueue.Dequeue();
    _sendArgs.SetBuffer(buff, 0, buff.Length);
    // SendAsync는 커널을 거드리는 함수이기에 속도가 느리다
    bool pending = _socket.SendAsync(_sendArgs));
    OnSendCompleted(null, _sendArgs);
}
List<ArraySegment<byte>> _pendingList = new List<ArraySegment<byte>>();
// ...
void RegisterSend()
{
    // byte[] buff = _sendQueue.Dequeue();
    // _sendArgs.SetBuffer(buff, 0, buff.Length);
    // 기존에는 SetBuffer로 버퍼를 지정해 보내줬지만
    // 버퍼의 리스트로 보내는 방법이 있다
    while(_sendQueue.Count > 0)
    {
        byte[] buff = _sendQueue.Dequeue();
        _pendingList.Add(new ArraySegment<byte>(buff, 0, buff.Length));
        // _sendArgs.BufferList.Add(new ArraySegment<byte>(buff, 0, buff.Length));
        // 참고로 위와 같이 Add를 해서 보내면 안됨(MSDN에 안된다고 나옴, 왜그런지는 잘;; MS에 물어봐야할 듯)
        /*
        개선점1 : 여기서 패킷이 너무 많을경우 너무 오래 잡고 있을 수 있음(이후 개선)
        */
    }
    _sendArgs.BufferList = _pendingList;
    // SendAsync는 커널을 거드리는 함수이기에 속도가 느리다
    bool pending = _socket.SendAsync(_sendArgs);
    if(pending == false)
        OnSendCompleted(null, _sendArgs);
}
// ...
    public void Send(byte[] sendBuff)
    {
        /*
        개선점2 : send가 필요한 데이터를 즉시 send하면 너무 많은 send가 일어난다.
        즉시 보내야할 데이터가 아닌경우 모아서 보내게 해야함
        */
        lock(_lock)
        {
            _sendQueue.Enqueue(sendBuff);
            if(_pendingList.Count == 0)
                // 대기중인 List가 없기에 Send를 Regist
                RegisterSend();
        }
    }
// ...
void OnSendComplete(object sender, SocketAsyncEventArgs args)
{
    lock(_lock)
    {
        if(args.BytesTransferred > 0 && args.SocketError ==SocketError.Success)
        {
            try{
                _sendArgs.BufferList = null;
                _pendingList.Clear();
                if(_sendQueue.Count > 0)
                    RegisterSend();
                
            }
            catch()
            {
            }
        }
        else
        {
            Disconnect();
        }
    }
}