2012-12-23 27 views
0

位停留在此,我...套接字 - 你可以把它另一个线程?

场景:

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

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

代码:

private static SnowTcpListener mServer; 

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

积压套接字积压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)); 
      } 
     } 

然后它会创建一个新的 “会话”

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

    mSocket.SendBufferSize = 512; 

    BeginReceive(); 
} 

其中依次调用BeginRecieve()

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

如果您需要了代码,只是问。

我将如何去创造它,因此连接是在一个单独的线程,或者我怎么会提高我的插座经验,都拿到一定数额的会话,它只是落后了。我试图增加缓冲区,但它使情况变得更糟。

我已经走到了我的束缚的尽头,我尝试了几乎所有我能想到的,我真的可以做一些帮助!

感谢您阅读这篇很长的文章,如果问题不明确,请尝试使它更清晰!

干杯 迈克

回答

1

你做了什么来评估现有的代码中的瓶颈和性能问题?你有没有使用任何工具分析它?

从发布到目前为止的代码中,您只是保持异步接收新连接(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(); 
} 
+0

这是辉煌的,它工作出色! – x06265616e

相关问题