标签: socketasynceventargs

20使用SocketAsyncEventArgs每秒接收

使用SocketAsyncEventArgs开发TCP服务器,它是Windows服务的异步方法.我在Main的开头有这两行代码:

ThreadPool.SetMaxThreads(15000, 30000);
ThreadPool.SetMinThreads(10000, 20000);
Run Code Online (Sandbox Code Playgroud)

并且都返回true(记录返回值).现在2000到3000个客户端开始向此服务器发送消息,它开始接受连接(我计算连接数,它是预期的 - 有一个连接池).服务器进程的线程数将增长到~2050到~3050.到现在为止还挺好!

现在有一个Received方法,在ReceiveAsync返回true或SocketAsyncEventArgs的Completed事件后调用.

问题就此开始了:无论客户端连接多少以及发送的消息数量多少,接收的消息最多只能在一秒钟内调用20次!随着客户数量的增加,这个数字(20)下降到~10.

环境:TCP服务器和客户端正在同一台计算机上进行模拟.我在两台机器上测试了代码,一台有2核CPU和4GB RAM,另一台有8核CPU和12GB RAM.(还没有)数据丢失,有时我在每次接收操作中都会收到多条消息.没关系.但是如何才能增加接收操作的数量?

关于实现的附加说明:代码很大,包含许多不同的逻辑.总体描述如下:我有一个SocketAsyncEventArgs用于接受新连接.它很棒.现在,对于每个新接受的连接,我创建一个新的SocketAsyncEventArgs来接收数据.我把这个(为接收创建的SocketAsyncEventArgs)放在一个池中.它不会被重用,但它的UserToken被用于跟踪连接; 例如那些断开连接的连接或那些7分钟内没有发送任何数据的连接将被关闭和处理(SocketAsyncEventArgs的AcceptSocket将被关闭(两者),关闭和处理,SocketAsyncEventArgs对象本身也是如此).这是一个执行这些任务的Sudo类,但所有其他逻辑和日志记录以及错误检查和其他任何内容都被删除,以使其简单明了(也许更容易发现有问题的代码):

class Sudo
{
    Socket _listener;
    int _port = 8797;

    public Sudo()
    {
        var ipEndPoint = new IPEndPoint(IPAddress.Any, _port);
        _listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        _listener.Bind(ipEndPoint);

        _listener.Listen(100);

        Accept(null);
    }

    void Accept(SocketAsyncEventArgs acceptEventArg)
    {
        if (acceptEventArg == null)
        {
            acceptEventArg = new SocketAsyncEventArgs();
            acceptEventArg.Completed += AcceptCompleted;
        }
        else acceptEventArg.AcceptSocket = null;

        bool willRaiseEvent = _listener.AcceptAsync(acceptEventArg); ;

        if (!willRaiseEvent) Accepted(acceptEventArg);
    }

    void AcceptCompleted(object sender, SocketAsyncEventArgs e)
    {
        Accepted(e); …
Run Code Online (Sandbox Code Playgroud)

c# sockets windows asynchronous socketasynceventargs

9
推荐指数
1
解决办法
6660
查看次数

C#SocketAsyncEventArgs处理接收和发送数据

我试图理解C#中的'SocketAsyncEventArgs'类.http://msdn.microsoft.com/en-us/library/system.net.sockets.socketasynceventargs.aspx

我正在关注本教程:http: //www.codeproject.com/Articles/83102/C-SocketAsyncEventArgs-High-Performance-Socket-Cod

现在我陷入了我应该如何处理我的服务器数据的问题.我想要做的是使用SocketAsyncEventArgs为BufferManager中分配的512字节缓冲区空间的连接客户端.那么我想要做的是将byte []数据解码为我自己的自定义类(ClientPacket),该类保存用于解码和读取的byte [].

这一切都很好,但我的服务器并不总是回答数据问题是:

我是否使用1个SocketAsyncEventArgs进行接收并循环处理接收数据,然后在需要发送时从池中分配SocketAsyncEventArgs然后在完成时返回它?

SocketAsyncEventArgs在读取完成时如何知道?(当它在用新数据覆盖它之前完成了byte []缓冲区),如果我没有回复,它如何在完成后返回池中?

c# sockets tcp socketasynceventargs

8
推荐指数
1
解决办法
8852
查看次数

如何将BufferList与SocketAsyncEventArgs一起使用而不是获取SocketError InvalidArgument?

我可以使用SetBuffer和SocketAsyncEventArgs就好了.

如果我尝试使用BufferList(在执行SetBuffer(null,0,0)之后),当我在套接字上执行SendAsync时,我总是立即得到SocketError InvalidArgument(10022).

关于如何使用BufferList没有任何示例或文档,我正在做的事情是有意义的(无论如何).

有人可以指出一个示例程序或代码片段吗?

我正在把头发撕掉,剩下的不多了......

这基本上是我在做什么(e是SocketAsyncEventArgs和lSocket是我用于SetBuffer的相同套接字,它有效)

// null the buffer since we will use a buffer list
e.SetBuffer(null, 0, 0);

// create a bufferlist
e.BufferList = new List<ArraySegment<byte>>();

// create the bufferlist with the network header and the response bytes
e.BufferList.Add(new ArraySegment<byte>(lTxBytes)); // add the 4 character total length
e.BufferList.Add(new ArraySegment<byte>(Encoding.ASCII.GetBytes(lTx.Identity))); // echo back the incoming sequence number
e.BufferList.Add(new ArraySegment<byte>(Encoding.ASCII.GetBytes(lResponse)));

// *** the SendAsync always completes IMMEDIATELY (returns false) gets SocketError InvalidArgument (10022)

if (lSocket.SendAsync(e) == false)
{
      // …
Run Code Online (Sandbox Code Playgroud)

.net c# system.net socketasynceventargs

7
推荐指数
1
解决办法
1947
查看次数

.NET异步套接字:在这种情况下SocketAsyncEventArgs在Begin/End上的任何好处是什么?

Socket具有这些新的异步方法,因为.NET 3.5与SocketAsyncEventArgs(例如Socket.SendAsync())一起使用,有利于它们使用IO完成端口并避免需要继续分配.

我们创建了一个名为UdpStream的类,具有简单的接口 - 只需StartSendCompleted事件.它分配两个SocketAsyncEventArgs,一个用于发送,一个用于接收.StartSend只是使用SendAsync调度消息,并且每秒调用大约10次.我们在接收SocketAsyncEventArgs上使用Completed事件,并在处理完每个事件后,我们所有的ReceiveAsync都会形成一个接收循环.同样,我们每秒大约收到10次.

我们的系统需要支持多达500个这些UdpStream对象.换句话说,我们的服务器将与500个不同的IP端点同时通信.

我注意到在MSDN SocketAsyncEventArgs示例中他们分配了N x SocketAsyncEventArgs,一个用于您希望一次处理的每个未完成的接收操作.我不清楚这与我们的场景究竟有什么关系 - 在我看来,也许我们没有得到SocketAsyncEventArgs的好处,因为我们只是为每个端点分配一个.如果我们最终获得500个SocketAsyncEventArgs,我认为我们将无法获益.也许我们仍然可以从IO完成端口获得一些好处?

  • 在扩展到500时,此设计是否正确使用SocketAsyncEventArgs?

  • 对于我们使用单个"UdpStream"的情况,使用SocketAsyncEventArgs与使用旧的Begin/End API相比有什么好处?

.net sockets asynchronous socketasynceventargs

5
推荐指数
2
解决办法
2344
查看次数

TcpListener 与 SocketAsyncEventArgs

是否有正当理由不TcpListener用于实现高性能/高吞吐量TCP服务器而不是SocketAsyncEventArgs

我已经实现了这个高性能/高吞吐量的 TCP 服务器,它使用SocketAsyncEventArgs了一个大的预先分配的byte数组和SocketAsyncEventArgs用于接受和接收的池来处理那些固定缓冲区,使用一些低级的东西和闪亮的智能组合在一起,经历了各种各样的麻烦带有一些 TPL 数据流和一些 Rx 的代码,它工作得很好;在这项工作中几乎是教科书 - 实际上我已经从其他人的代码中学到了 80% 以上的这些东西。

但是也存在一些问题和顾虑:

  1. 复杂性:我不能将对该服务器的任何修改委托给团队的其他成员。这将我限制在此类任务中,我无法对其他项目的其他部分给予足够的关注。
  2. 内存使用(固定byte数组):使用SocketAsyncEventArgs池需要预先分配。因此,为了处理 100000 个并发连接(更糟糕的情况,即使在不同的端口上),一大堆 RAM 无用地徘徊在那里;预先分配(即使这些条件只是在某些时候满足,服务器每天应该能够处理 1 或 2 个这样的峰值)。
  3. TcpListener实际上效果很好:我实际上已经进行TcpListener了测试(使用了一些技巧,例如AcceptTcpClient在专用线程上使用,而不是 async 版本,然后将接受的连接发送到 a ConcurrentQueue而不是Task就地创建s 等)和最新版本的 . NET,它运行得非常好,几乎与SocketAsyncEventArgs.

那么为什么我没有看到TcpListener在任何地方使用并且每个人(包括我自己)都在使用SocketAsyncEventArgs?我错过了什么吗?

c# sockets tcplistener tcpserver socketasynceventargs

5
推荐指数
1
解决办法
4255
查看次数

如何在从SocketAsyncEventArgs继承的类中实现IDisposable接口

我在C#.NET 4.0中处理一个庞大的项目.有一个从System.Net.Sockets继承的自定义类.SocketAsyncEventArgs类.类似于以下内容:

public class SocketTaskArgs : SocketAsyncEventArgs
{
    public SocketTaskArgs()
    {
        Completed += someEventhHandler;
    }

    public void CleanUp()
    {
        Completed -= someEventhHandler;
    }

    /* 
        There is a lot of code here that is unimportant at the moment.
    */
}
Run Code Online (Sandbox Code Playgroud)

所以,我想将CleanUp()方法的内容移到Dispose(bool)方法.

首先,我检查了基类的源代码 - SocketAsyncEventArgs(使用Go To Definition,因此我将元数据视为源代码).我发现,这个类实现了IDisposable接口.很好,我只需要覆盖Dispose(bool)方法,不是吗?(有关详细信息,请参阅MSDN上的IDisposable接口," IDisposable和继承层次结构 "部分).对我来说没什么新东西......不幸的是,SocketAsyncEventArgs类实现如下:

public class SocketAsyncEventArgs : EventArgs, IDisposable
{
    public void Dispose();

    //some other stuff here
}
Run Code Online (Sandbox Code Playgroud)

这意味着,没有办法如何覆盖Dispose(bool)方法,因为它实现为私有而不是受保护 ...... 这是什么原因?

接下来,我在MSDN上阅读有关 …

c# inheritance dispose idisposable socketasynceventargs

5
推荐指数
1
解决办法
1156
查看次数

如何使用Socket.SendAsync发送大数据

private void ProcessReceive(SocketAsyncEventArgs e)
{
    // Check if the remote host closed the connection.
    if (e.BytesTransferred > 0)
    {
        if (e.SocketError == SocketError.Success)
        {
            Token token = e.UserToken as Token;
            token.SetData(e);

            Socket s = token.Connection;
            if (s.Available == 0)
            {
                Boolean willRaiseEvent = false;
                // GET DATA TO SEND
                byte[] sendBuffer = token.GetRetBuffer();
                // this.bufferSize IS SocketAsyncEventArgs buffer SIZE
                byte[] tempBuffer = new byte[this.bufferSize];
                int offset = 0;
                int size = (int)Math.Ceiling((double)sendBuffer.Length / (double)this.bufferSize);
                for (int i = 0; i …
Run Code Online (Sandbox Code Playgroud)

c# sockets sendasync socketasynceventargs

3
推荐指数
1
解决办法
2万
查看次数

具有1000个客户端的开始/结束vs socketasynceventargs

我想知道哪种异步类型在开发速度和稳定性方面都是最好的.我正在编写一个概念证明网络应用程序,它必须支持1000个concurent客户端.

每个客户端每秒发送大约5个30字节的数据包.服务器每秒发送大约5个200字节的数据包.

我从早期的测试中得到了这些数字,带有阻塞套接字.我认为我应该使用SocketAsyncEventArgs导致高吞吐量,但开发时间也需要更长的时间.

谢谢

.net sockets networking socketasynceventargs

2
推荐指数
1
解决办法
880
查看次数