服务端与客户端交互(二)

1.增加服务端异步的消息接收
2.修改服务器端开启异步处理客户端的请求
3.处理服务端处理客户端的连接正常关闭和非正常关闭
1.异步接收客户端发送过来的消息,上一篇接受客户端消息是在主线程中等待客户端发送,会造成主线程运行阻塞,这里调整为异步接受
主要方法:BeginReceive(字节数组,数组读取偏移,读取长度,SocketFlags.None,相应异步操作完成时回调方法,接受操作的相关信息);//开始监听客户端数据的传递,当接收到客户端数据时才调用传入的回调函数

2.同时接受多个客户端发送的消息。
主要方法:BeginAccept(相应异步操作完成时回调方法,接受操作的相关信息)//开始一个异步操作来接受一个传入的链接尝试。

3.客户端非正常关闭时服务端会抛出异常,客户端关闭是通知服务端
Try{}catch(){}捕捉异常处理
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;

namespace JungleWarServer
{
    class Program
    {
        static void Main(string[] args)
        {
            StartServerAsync();
            //StartServerSync();
            Console.ReadKey();
        }
        static void StartServerAsync()
        {
            //1.创建服务端套接字
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //2.创建服务端ip地址与端口号
            IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
            IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 666);
            //3.服务端与ip地址端口号绑定
            serverSocket.Bind(ipEndPoint);
            serverSocket.Listen(50);//开始监听端口号,处理链接的队列

            //Socket clientSocket = serverSocket.Accept();//接收一个客户端链接
            serverSocket.BeginAccept(StartClientServerAsync, serverSocket);
        }

        private static void StartClientServerAsync(IAsyncResult ar)
        {
            Socket serverSocket = ar.AsyncState as Socket;
            Socket clientSocket = serverSocket.EndAccept(ar);
            //向客户端发送消息
            string str = "Hello !客户端。。。";
            byte[] data = System.Text.Encoding.UTF8.GetBytes(str);
            clientSocket.Send(data);
            //异步接收客户端发送的消息,异步不阻塞主线程
            //开始监听客户端数据的传递,当接收到客户端数据时才调用传入的回调函数
            clientSocket.BeginReceive(dataBuffer, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);
            serverSocket.BeginAccept(StartClientServerAsync, serverSocket);
            
        }

        static byte[] dataBuffer = new byte[1024];
        private static void ReceiveCallBack(IAsyncResult ar)
        {
            Socket clientSocket =null;
            try
            {
                clientSocket = ar.AsyncState as Socket;
                int count = clientSocket.EndReceive(ar);
                if (count==0)
                {
                    clientSocket.Close();
                    return;
                }
                string strReceive = Encoding.UTF8.GetString(dataBuffer, 0, count);
                Console.WriteLine(strReceive);
                clientSocket.BeginReceive(dataBuffer, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);
            }
            catch (Exception ex)
            {

                Console.WriteLine(ex.Message);
                if (clientSocket!=null)
                {
                    clientSocket.Close();
                }
            }
          
        }

       static void StartServerSync()
        {
            //1.创建服务端套接字
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //2.创建服务端ip地址与端口号
            IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
            IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 666);
            //3.服务端与ip地址端口号绑定
            serverSocket.Bind(ipEndPoint);
            serverSocket.Listen(50);//开始监听端口号,处理链接的队列
            Socket clientSocket = serverSocket.Accept();//接收一个客户端链接
            //向客户端发送消息
            string str = "Hello !客户端。。。";
            byte[] data = System.Text.Encoding.UTF8.GetBytes(str);
            clientSocket.Send(data);
            //接收客户端发送的消息
            byte[] dataBuffer = new byte[1024];
            int count = clientSocket.Receive(dataBuffer);//接收到的消息存储进数组缓存区,返回存储的长度。
            string msgReceive = Encoding.UTF8.GetString(dataBuffer, 0, count); //字节数组转为消息,需指定长度

            Console.WriteLine(msgReceive);
            Console.ReadKey();
            serverSocket.Close();
        }

    }
}
客户端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
using System.Collections;

namespace JungleWarClient
{
    class Program
    {
        static void Main(string[] args)
        {
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            clientSocket.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 666));

            //接收从服务器发送过来的消息
            byte[] data = new byte[1024];
            int count = clientSocket.Receive(data);
            string strReceive = Encoding.UTF8.GetString(data, 0, count);
            Console.WriteLine(strReceive);

            //向服务器发送消息
            while (true)
            {
                string strSend = Console.ReadLine();
                if (strSend=="c")
                {
                    clientSocket.Close();
                    return;
                }
                byte[] dataSend = Encoding.UTF8.GetBytes(strSend);
                clientSocket.Send(dataSend);
            }
        }

    }
}



你可能感兴趣的:(编程指南)