• SocketAsyncEventArgs里的AcceptSocket能独立存在吗?


    独立存在是什么意思?

    先来看一个例子.我们知道一个Socket对象(我们叫他ListenScoket)可以调用AcceptAsync并接受一个SocketAsyncEventArgs对象,如果操作成功则ListenSocket会为SocketAsyncEventArgs对象创建一个新的Socket对象(我们叫它AcceptSccket)。也就是这样

    listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    listenSocket.Bind(new IPEndPoint(IPAddress.Parse("10.175.5.172"), 60000));
    listenSocket.Listen(10);
    SocketAsyncEventArgs asyncEventArgs =new SocketAsyncEventArgs();
    asyncEventArgs.Completed += asyncEventArgs_Completed;
    listenSocket.AcceptAsync(asyncEventArgs);

    如果ListenSocket关闭之后AcceptSocket还可以正常工作,那么我们就说AcceptSocket是独立存在的.

    那到底AcceptSocket能否独存在呢?

    首先我们来看AcceptSocket是什么时候创建的.其实当listenSocket.AcceptAsync(asyncEventArgs)执行的时候SocketAsyncEventArgs内部的AcceptSocket就已经被创建了,但是它不能被用来发送和接收数据.假如我们在AcceptAsync之后紧跟着调用AcceptSocket来发送一个”OK”字符串,那么会得到这样一个错误:

    'asyncEventArgs.AcceptSocket.Send(ASCIIEncoding.ASCII.GetBytes("OK"))' threw an exception of type 'System.Net.Sockets.SocketException'
        base: {"A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied"}
        ErrorCode: 10057
        Message: "A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied"
        SocketErrorCode: NotConnected

    注意错误消息中被标为红色的部分,这说明AcceptSocket对象已经创建了,不过没有可用的地址,也就是没有客户端IP和端口.这个很好理解,因为客户端还没有连接上呢.当客户端连接成功的时候,ListenSocket会将客户端的地址(IP和端口)赋予AcceptSocket.同时,SocketAsyncEventArgs的Completed事件会被触发,我们就知道AcceptSocket可以正常使用了.

    为什么会有这个疑问呢? 在我们的应用中ListenSocket会创建很多的AcceptSocket, 某一个时刻我们想停止接收更多新的Socket连接,同时又想保持现有的连接,那么我们可以直接把ListenSocket关闭.经过测试是不需要担心AcceptSocket会受到影响的.也就是说AcceptSocket可以独立存在的. 下面是测试代码. 

    using System;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace SocketAsyncEventArgsTest
    {
        class Program
        {
            static int socketCount = 0;
            static Socket listenSocket;
            static void Main(string[] args)
            {
                listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                listenSocket.Bind(new IPEndPoint(IPAddress.Parse("10.175.5.172"), 60000));
                listenSocket.Listen(10);
                SocketAsyncEventArgs asyncEventArgs =new SocketAsyncEventArgs();
                asyncEventArgs.Completed += asyncEventArgs_Completed;
                listenSocket.AcceptAsync(asyncEventArgs);
    
                SocketAsyncEventArgs asyncEventArgs2 = new SocketAsyncEventArgs();
                asyncEventArgs2.Completed += asyncEventArgs_Completed;
                listenSocket.AcceptAsync(asyncEventArgs2);
    
                //listenSocket.Close();
    
                Console.Read();
            }
    
            static void asyncEventArgs_Completed(object sender, SocketAsyncEventArgs e)
            {
                if (SocketError.Success == e.SocketError)
                {
                    socketCount++;
                    if (2 == socketCount)
                        // Close the listen socket will not close the accept sockets opened by it.
                        // so the accept socket can continue receive/send data normally.
                        listenSocket.Close();
    
                    Socket acceptSocket = e.AcceptSocket;
                    byte[] buffer=new byte[1024];
                    Task.Factory.StartNew(() =>
                    {
                        while(true)
                        {
                            acceptSocket.Receive(buffer);
                            Console.WriteLine(ASCIIEncoding.ASCII.GetString(buffer));
                            acceptSocket.Send(ASCIIEncoding.ASCII.GetBytes("OK"));
                        }
                    });
                }
            }
        }
    }
  • 相关阅读:
    LIGGGHTS中的restart命令
    paraview计算面上的流量
    paraview计算面上的平均压力
    paraview计算区域中的平均流速
    paraview提取非常好看的流线图
    paraview显示颗粒的快捷方法
    paraview显示网格很多线条重合问题
    CFDEM中writeLiggghtsProps命令
    paraview使用ExtractCellsByRegion提取球阀阀芯中的颗粒数量
    Paraview 显示模拟时间
  • 原文地址:https://www.cnblogs.com/rader/p/4354236.html
Copyright © 2020-2023  润新知