C#Socket异步通讯学习

异步通信:

之前写得聊天室是基于同步通信的,使用的Socket.Accept(), Socket.Receive()等方法。同步的方法实现起来简单,但是它是在一个任务处理完之后,然后才能再进行接收。现在使用异步的方法来实现它,当一个任务正在进行中时,又有一个任务进来,那么就会另开一个线程来处理它,使得可以同时进行几个会话。

同样使用控制台来实现一个聊天室

服务端:
声明一个静态方法StartServer,用来声明Socket,绑定IP和端口,并开始监听10台计算机

static void BindIP()
        {
        //声明服务器端的Socket
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //声明IP地址和端口号
            IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
            EndPoint ipEndPoint = new IPEndPoint(ipAddress,7788);
            //将serverSocket和IP终节点进行绑定
            serverSocket.Bind(ipEndPoint);
            //监听最大的接入量为10
            serverSocket.Listen(10);
//开始异步连接      
      serverSocket.BeginAccept(AcceptCallBack,serverSocket);
        }

这里serverSocket使用的是BeginAccept()方法,参数要求的是AsyncCallBack(回调方法)和一个Object(对象),这里传入的是回调函数AcceptCallBack和对象serverSocket它本身。
当开启BeginAccept()时,这个方法会开始调用回调方法,并且将后面的Object作为一个参数传入到回调方法中。开始回调方法后,我们要求的后续操作会在回调方法中继续执行。

下面是回调方法AcceptCallBack()

static void AcceptCallBack(IAsyncResult result)
        {
        //上面讲serverSocket本身传入回调方法中,现在要接收这个Socket。
            Socket serverSocket = result.AsyncState as Socket;
            //在接收到一台要连入的计算机后,我们要获得接入的计算机的信息,//就需要一个Socket专门用于和它通信。我们再声明一个clientSocket,//用于接收和发送接入方的数据
            Socket clientSocket=serverSocket.EndAccept(result);
//在获得这个clientSocket后,使用BeginReceive方法来接收数据 
           clientSocket.BeginReceive(data,0,1024,SocketFlags.None,ReceiveCallBack, clientSocket);
//建立了通信,开启接收数据后,我们要循环接收其他要连接的计算机,所以这里接着进行等待接收,这样就实现了一个循环不断的接收
            serverSocket.BeginAccept(AcceptCallBack, serverSocket);
        }

回调方法ReceiveCallBack()

  static void ReceiveCallBack(IAsyncResult result)
        {
            //声明一个空的Socket
            Socket clientSocket = null;
            //当客户端被暴力关掉后,会造成服务器端的报警,这里将它try catch起来,防止程序崩溃
            try
            {
                //将传入的clientSocket进行接收,并且完成接收数据的操作
                clientSocket = result.AsyncState as Socket;
                int length = clientSocket.EndReceive(result);
                string message = Encoding.UTF8.GetString(data, 0, length);

                //如果客户端正常关闭后,会向服务端发送长度为0的空数据,利用这一点将这个客户端关闭
                if (length==0)
                {
                    clientSocket.Close();
                    return;
                }
                Console.WriteLine("收到消息:" + message);
                //重新调用开始接收数据
                clientSocket.BeginReceive(data, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);
            }
            catch (Exception e)
            { 
                Console.WriteLine(e);
                if(clientSocket!=null)
                {
                    clientSocket.Close();
                }
            }

        }

客户端
跟上一个聊天室一样,除了使用字符c来控制关闭

  static Socket clientSocket;
        static void Main(string[] args)
        {
            clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
            EndPoint ipEndPoint = new IPEndPoint(ipAddress, 7788);

            clientSocket.Connect(ipEndPoint);
            byte[] dataBuffer = new byte[1024];

            while(true)
            {
                Console.WriteLine("输入数据:");
                string s = Console.ReadLine();
                //当输入c时,Socket关闭
                if(s=="c")
                {
                    clientSocket.Close();
                    return;
                }
                dataBuffer = Encoding.UTF8.GetBytes(s);
                clientSocket.Send(dataBuffer);
            }


            Console.ReadKey();
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值