随笔 - 120  文章 - 0  评论 - 902  阅读 - 51万

利用.net Socket 的Acceptex方法加速你的连接

今天因为一个需要,要研究一下sock的异步性能,就用Reflector看了看。发现在调用的时候.net优先调用的是acceptex的 api,而不是accept api。在msdn里查看了一下这两者的区别:

The AcceptEx function uses overlapped I/O, unlike the accept function. If your application uses AcceptEx, it can service a large number of clients with a relatively small number of threads. As with all overlapped Windows functions, either Windows events or completion ports can be used as a completion notification mechanism.

 

Another key difference between the AcceptEx function and the accept function is that AcceptEx requires the caller to already have two sockets:

  • One that specifies the socket on which to listen.
  • One that specifies the socket on which to accept the connection.


it can service a large number of clients with a relatively small number of threads
这句话那是非常的诱人啊!

那我们再来看看什么情况下可以使用这个扩展的Accept呢?

首先在.net的Accept非异步函数里面是不可以调用这个的,只有在异步调用里面才有:BeginAccept方法
其反编译后如下:
[HostProtection(SecurityAction.LinkDemand, ExternalThreading=true)]
public IAsyncResult BeginAccept(AsyncCallback callback, object state)
{
    
if (this.CanUseAcceptEx)
    
{
        
return this.BeginAccept(0, callback, state);
    }

    
if (s_LoggingEnabled)
    
{
        Logging.Enter(Logging.Sockets, 
this"BeginAccept""");
    }

    
if (this.CleanedUp)
    
{
        
throw new ObjectDisposedException(base.GetType().FullName);
    }

    AcceptAsyncResult asyncResult 
= new AcceptAsyncResult(this, state, callback);
    asyncResult.StartPostingAsyncOp(
false);
    
this.DoBeginAccept(asyncResult);
    asyncResult.FinishPostingAsyncOp(
ref this.Caches.AcceptClosureCache);
    
if (s_LoggingEnabled)
    
{
        Logging.Exit(Logging.Sockets, 
this"BeginAccept", asyncResult);
    }

    
return asyncResult;
}



下面是CanuseAcceptEx属性的反编译:
private bool CanUseAcceptEx
{
    
get
    
{
        
if (!ComNetOS.IsWinNt)
        
{
            
return false;
        }

        
if (!Thread.CurrentThread.IsThreadPoolThread && !SettingsSectionInternal.Section.AlwaysUseCompletionPortsForAccept)
        
{
            
return this.m_IsDisconnected;
        }

        
return true;
    }

}

 
那个iswinnt还没有找到相关资料,不过看字面意思看起来是平台相关的,是winnt系统应该都可以。
另外检验其他的是否为线程池和是否总是使用完成端口的检测如果不通过的话就检测连接是否还连接着。

其中再各个重载方法中,最重要的是检测IsWinNt选项,要不然就不会执行这个AcceptEx方法。
posted on   Keep Walking  阅读(1604)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述
< 2008年4月 >
30 31 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 1 2 3
4 5 6 7 8 9 10

点击右上角即可分享
微信分享提示