你能给它另一个线程吗?

本文关键字:线程 另一个 | 更新日期: 2023-09-27 17:49:17

有点卡住了,我是…

场景:一个套接字处理游戏模拟器发送和接收编码的数据编码在VL64和其他字符串。需要支持约4000套接字请求等

目前它使用AsyncCallback来执行异步服务器角色等。

代码:

private static SnowTcpListener mServer;
mServer = new SnowTcpListener(new IPEndPoint(IPAddress.Any, "IP"), backlog, new OnNewConnectionCallback(SessionManager.HandleIncomingConnection));

Backlog是Socket Backlog的int类型。

SnowTcpListener

/// <summary>
    /// Callback to be invoked upon accepting a new connection.
    /// </summary>
    /// <param name="Socket">Incoming socket connection</param>
    public delegate void OnNewConnectionCallback(Socket Socket);
    /// <summary>
    /// Reality simple asynchronous TCP listener.
    /// </summary>
    public class SnowTcpListener : IDisposable // Snow prefix to avoid conflicts with System.Net.TcpListener
    {
        private Socket mSocket;
        private OnNewConnectionCallback mCallback;
        public SnowTcpListener(IPEndPoint LocalEndpoint, int Backlog, OnNewConnectionCallback Callback)
        {
            mCallback = Callback;
            mSocket = new Socket(LocalEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            mSocket.Bind(LocalEndpoint);
            mSocket.Listen(Backlog);
            BeginAccept();
        }
        public void Dispose()
        {
            if (mSocket != null)
            {
                mSocket.Dispose();
                mSocket = null;
            }
        }
        private void BeginAccept()
        {
            try
            {
                mSocket.BeginAccept(OnAccept, mSocket);
            }
            catch (Exception) { }
        }
        private void OnAccept(IAsyncResult Result)
        {
            try
            {
                Socket ResultSocket = (Socket)mSocket.EndAccept(Result);
                mCallback.Invoke(ResultSocket);
            }
            catch (Exception) { }
            BeginAccept();
        }

SessionManager。HandleIncomingConnection:

public static void HandleIncomingConnection(Socket IncomingSocket)
        {
            bool Reject = ModerationBanManager.IsRemoteAddressBlacklisted(IncomingSocket.RemoteEndPoint.ToString().Split(':')[0]);
            Output.WriteLine((Reject ? "Rejected" : "Accepted") + " incoming connection from " + IncomingSocket.RemoteEndPoint.ToString() + ".",
                OutputLevel.Informational);
            if (Reject)
            {
                try
                {
                    IncomingSocket.Close();
                }
                catch (Exception) { }
                return;
            }
            lock (mSyncRoot)
            {
                uint Id = mCounter++;
                mSessions.Add(Id, new Session(Id, IncomingSocket));
            }
        }

然后创建一个新的Session

public Session(uint Id, Socket Socket)
{
    mId = Id;
    mSocket = Socket;
    mBuffer = new byte[512];
    mPongOk = true;
    mSocket.SendBufferSize = 512;
    BeginReceive();
}

调用beginreceive ()

private void BeginReceive()
        {
            try
            {
                if (mSocket != null)
                {
                    //TODO: BeginRecieve();
                    mSocket.BeginReceive(mBuffer, 0, mBuffer.Length, SocketFlags.None, new AsyncCallback(OnReceiveData), mSocket);
                }
            }
            catch (Exception)
            {
                SessionManager.StopSession(mId);
            }
        }

OnRecieveData ()

private void OnReceiveData(IAsyncResult Result)
        {
            int ByteCount = 0;
            try
            {
                if (mSocket != null)
                {
                    ByteCount = mSocket.EndReceive(Result);
                }
            }
            catch (Exception) { }
            if (ByteCount < 1 || ByteCount >= mBuffer.Length)
            {
                SessionManager.StopSession(mId);
                return;
            }
            ProcessData(ByteUtil.ChompBytes(mBuffer, 0, ByteCount));
            BeginReceive();
        }

如果你需要更多的代码,就问我。

我将如何去创建它,所以连接是在一个单独的线程,或者我将如何提高我的套接字体验,因为我得到一定数量的会话,它只是滞后。我试过增加缓冲区,但它使情况变得更糟。

我已经穷途末路了,我已经尝试了几乎所有我能想到的,我真的需要一些帮助!

感谢阅读这篇很长的文章,如果问题不清楚,我会尽量让你更清楚!

干杯迈克

你能给它另一个线程吗?

您如何评估现有代码中的瓶颈和性能问题?你用什么工具分析过它吗?

从代码张贴到目前为止,你只是保持异步接收新连接(BeginAccept)和传入数据(BeginReceive)。这些都不会导致性能下降。但是BeginReceive函数调用"ProcessData",这可能是处理消息的所有业务逻辑所在。我怀疑这就是你的瓶颈所在。但这只是猜测。

你说4000个套接字,所以"每个连接一个线程"听起来不像是正确的设计。

但是既然你已经在做异步套接字,那么正确的方法似乎是在工作池线程中调用ProcessData。当ProcessData完成时,只需在会话对象上再次调用BeginReceive。如下所示:

private void OnReceiveData(IAsyncResult Result)
{
    int ByteCount = 0;
    try
    {
        if (mSocket != null)
        {
            ByteCount = mSocket.EndReceive(Result);
        }
    }
    catch (Exception) { }
    if (ByteCount < 1 || ByteCount >= mBuffer.Length)
    {
        SessionManager.StopSession(mId);
        return;
    }
    ThreadPool.QueueUserWorkItem(ProcessDataInThread, ByteCount);
}
void ProcessDataInThread(object context)
{
    int ByteCount = (int)context;
    ProcessData(ByteUtil.ChompBytes(mBuffer, 0, ByteCount));
    BeginReceive();
}