Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 插座-你能把它换成另一根线吗?_C#_Sockets - Fatal编程技术网

C# 插座-你能把它换成另一根线吗?

C# 插座-你能把它换成另一根线吗?,c#,sockets,C#,Sockets,我被这件事卡住了 情景: 一个套接字处理游戏模拟器,用于发送和接收编码为VL64和其他字符串的编码数据。需要支持大约4000个套接字请求等 目前,它使用AsyncCallback执行异步服务器角色等 代码: Backlog是套接字Backlog的int 雪撬 /// <summary> /// Callback to be invoked upon accepting a new connection. /// </summary> /// <

我被这件事卡住了

情景:

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

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

代码:

Backlog是套接字Backlog的int

雪撬

/// <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();
        }
然后创建一个新的“会话”

哪个inturn称为BeginRecieve()

OnReceiveData()

ReceiveData上的私有void(IAsyncResult结果)
{
int字节数=0;
尝试
{
if(mSocket!=null)
{
字节数=mSocket.EndReceive(结果);
}
}
捕获(异常){}
if(字节数<1 | |字节数>=mBuffer.Length)
{
SessionManager.StopSession(mId);
返回;
}
ProcessData(ByteUtil.ChompBytes(mBuffer,0,ByteCount));
BeginReceive();
}
如果您需要更多的代码,请询问

我将如何创建它,使连接在一个单独的线程中,或者如何改进我的套接字体验,因为我们进入了一定数量的会话,它只是滞后了。我试图增加缓冲区,但它使情况变得更糟

我现在已经穷途末路了,我已经尝试了我能想到的一切,我真的可以在一些帮助下做到

谢谢你阅读这篇很长的帖子,如果问题不清楚,我会尽量让你明白

干杯
Mike

为了评估现有代码中的瓶颈和性能问题,您做了哪些工作?您是否使用任何工具对其进行了分析

从目前发布的代码来看,您只需保持异步接收新连接(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();
}
ReceiveData上的私有void(IAsyncResult结果)
{
int字节数=0;
尝试
{
if(mSocket!=null)
{
字节数=mSocket.EndReceive(结果);
}
}
捕获(异常){}
if(字节数<1 | |字节数>=mBuffer.Length)
{
SessionManager.StopSession(mId);
返回;
}
QueueUserWorkItem(ProcessDataInThread,字节数);
}
void ProcessDataInThread(对象上下文)
{
int字节计数=(int)上下文;
ProcessData(ByteUtil.ChompBytes(mBuffer,0,ByteCount));
BeginReceive();
}

这真是太棒了,而且效果非常好!
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));
            }
        }
public Session(uint Id, Socket Socket)
{
    mId = Id;
    mSocket = Socket;
    mBuffer = new byte[512];
    mPongOk = true;

    mSocket.SendBufferSize = 512;

    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);
            }
        }
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();
        }
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();
}