zoukankan      html  css  js  c++  java
  • C#实现异步阻塞TCP(Send,Receive,Accept,Connect)

    1.类

    (1)服务器端操作类

        public class TcpServiceSocket
        {
            //接收数据事件
            public Action<Socket, string> recvMessageEvent = null;
            //发送结果事件
            public Action<int> sendResultEvent = null;
            //允许连接到tcp服务器的tcp客户端数量
            private int numConnections = 0;
            //连接socket
            private Socket listenSocket = null;
            //tcp服务器ip
            private string host = "";
            //tcp服务器端口
            private int port = 0;
            //控制tcp客户端连接数量的信号量
            private Semaphore maxNumberAcceptedClients = null;
            private int bufferSize = 1024;
            private List<Socket> clientSockets = null;
    
            public TcpServiceSocket(string host, int port, int numConnections)
            {
                if (string.IsNullOrEmpty(host))
                    throw new ArgumentNullException("host cannot be null");
                if (port < 1 || port > 65535)
                    throw new ArgumentOutOfRangeException("port is out of range");
                if (numConnections <= 0 || numConnections > int.MaxValue)
                    throw new ArgumentOutOfRangeException("_numConnections is out of range");
    
                this.host = host;
                this.port = port;
                this.numConnections = numConnections;
                clientSockets = new List<Socket>();
                maxNumberAcceptedClients = new Semaphore(numConnections, numConnections);
            }
    
            public void Start()
            {
                try
                {
                    listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    listenSocket.Bind(new IPEndPoint(IPAddress.Parse(host), port));
                    listenSocket.Listen(numConnections);
                    AcceptAsync();
                }
                catch (Exception)
                {
                }
            }
    
            private async void AcceptAsync()
            {
                await Task.Run(new Action(() =>
                {
                    while (true)
                    {
                        maxNumberAcceptedClients.WaitOne();
    
                        try
                        {
                            Socket acceptSocket = listenSocket.Accept();
                            if (acceptSocket == null)
                                continue;
    
                            clientSockets.Add(acceptSocket);
                            RecvAsync(acceptSocket);
                        }
                        catch (Exception)
                        {
                            maxNumberAcceptedClients.Release();
                        }
                    }
                }));
            }
    
            private async void RecvAsync(Socket acceptSocket)
            {
                await Task.Run(new Action(() =>
                {
                    int len = 0;
                    byte[] buffer = new byte[bufferSize];
    
                    try
                    {
                        while ((len = acceptSocket.Receive(buffer, bufferSize, SocketFlags.None)) > 0)
                        {
                            if (recvMessageEvent != null)
                                recvMessageEvent(acceptSocket, Encoding.UTF8.GetString(buffer, 0, len));
                        }
                    }
                    catch (Exception)
                    {
                        CloseClientSocket(acceptSocket);
                    }
                }));
            }
    
            public async void SendAsync(Socket acceptSocket, string message)
            {
                await Task.Run(new Action(() =>
                {
                    int len = 0;
                    byte[] buffer = Encoding.UTF8.GetBytes(message);
                    try
                    {
                        if ((len = acceptSocket.Send(buffer, buffer.Length, SocketFlags.None)) > 0)
                        {
                            if (sendResultEvent != null)
                                sendResultEvent(len);
                        }
                    }
                    catch (Exception)
                    {
                        CloseClientSocket(acceptSocket);
                    }
                }));
            }
    
            public async void SendMessageToAllClientsAsync(string message)
            {
                await Task.Run(new Action(() =>
                {
                    foreach (var socket in clientSockets)
                    {
                        SendAsync(socket, message);
                    }
                }));
            }
    
            private void CloseClientSocket(Socket acceptSocket)
            {
                try
                {
                    acceptSocket.Shutdown(SocketShutdown.Both);
                }
                catch { }
                try
                {
                    acceptSocket.Close();
                }
                catch { }
    
                maxNumberAcceptedClients.Release();
            }
    
            public void CloseAllClientSocket(Socket acceptSocket)
            {
                try
                {
                    foreach (var socket in clientSockets)
                    {
                        socket.Shutdown(SocketShutdown.Both);
                    }
                }
                catch { }
                try
                {
                    foreach (var socket in clientSockets)
                    {
                        socket.Close();
                    }
                }
                catch { }
    
                try
                {
                    listenSocket.Shutdown(SocketShutdown.Both);
                }
                catch { }
                try
                {
                    listenSocket.Close();
                }
                catch { }
    
                try
                {
                    maxNumberAcceptedClients.Release(clientSockets.Count);
                    clientSockets.Clear();
                }
                catch { }
            }
        }
    

      

    (2)客户端操作类

        public class TcpClientSocket
        {
            //接收数据事件
            public Action<string> recvMessageEvent = null;
            //发送结果事件
            public Action<int> sendResultEvent = null;
            //连接socket
            private Socket connectSocket = null;
            //tcp服务器ip
            private string host = "";
            //tcp服务器端口
            private int port = 0;
            private int bufferSize = 1024;
    
            public TcpClientSocket(string host, int port)
            {
                if (string.IsNullOrEmpty(host))
                    throw new ArgumentNullException("host cannot be null");
                if (port < 1 || port > 65535)
                    throw new ArgumentOutOfRangeException("port is out of range");
    
                this.host = host;
                this.port = port;
            }
    
            public void Start()
            {
                try
                {
                    connectSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    connectSocket.Connect(host, port);
                    RecvAsync();
                }
                catch (Exception)
                {
                }
            }
    
            private async void RecvAsync()
            {
                await Task.Run(new Action(() =>
                {
                    int len = 0;
                    byte[] buffer = new byte[bufferSize];
                    try
                    {
                        while ((len = connectSocket.Receive(buffer, bufferSize, SocketFlags.None)) > 0)
                        {
                            if (recvMessageEvent != null)
                                recvMessageEvent(Encoding.UTF8.GetString(buffer, 0, len));
                        }
                    }
                    catch (Exception)
                    {
                        Restart();
                    }
                }));
            }
    
            public async void SendAsync(string message)
            {
                await Task.Run(new Action(() =>
                {
                    int len = 0;
                    byte[] buffer = Encoding.UTF8.GetBytes(message);
                    try
                    {
                        if ((len = connectSocket.Send(buffer, buffer.Length, SocketFlags.None)) > 0)
                        {
                            if (sendResultEvent != null)
                                sendResultEvent(len);
                        }
                    }
                    catch (Exception)
                    {
                        Restart();
                    }
                }));
            }
    
            public void CloseClientSocket()
            {
                try
                {
                    connectSocket.Shutdown(SocketShutdown.Both);
                }
                catch { }
                try
                {
                    connectSocket.Close();
                }
                catch { }
            }
    
            public void Restart()
            {
                CloseClientSocket();
                Start();
            }
    
        }
    

      

    2.使用

    (1)服务器:

        public partial class Form1 : Form
        {
            TcpServiceSocket tcpServiceSocket = null;
            private readonly string ip = "192.168.172.142";
            private readonly int port = 8090;
    
            public Form1()
            {
                InitializeComponent();
                tcpServiceSocket = new TcpServiceSocket(ip, port, 10);
                tcpServiceSocket.recvMessageEvent += new Action<Socket, string>(Recv);
            }
    
            private void Recv(Socket socket, string message)
            {
                this.BeginInvoke(new Action(() =>
                {
                    tbRecv.Text += message + "
    ";
                }));
            }
    
            private void btnStart_Click(object sender, EventArgs e)
            {
                tcpServiceSocket.Start();
            }
    
            private void btnSend_Click(object sender, EventArgs e)
            {
                string message = tbSend.Text.Trim();
                if (string.IsNullOrEmpty(message))
                    return;
    
                tcpServiceSocket.SendMessageToAllClientsAsync(message);
                tbSend.Text = "";
            }
        }
    

      

    (2)客户端

        public partial class Form1 : Form
        {
            private TcpClientSocket tcpClientSocket = null;
            private readonly string ip = "192.168.172.142";
            private readonly int port = 8090;
    
            public Form1()
            {
                InitializeComponent();
                tcpClientSocket = new TcpClientSocket(ip, port);
                tcpClientSocket.recvMessageEvent += new Action<string>(Recv);
            }
    
            private void Recv(string message)
            {
                this.BeginInvoke(new Action(() =>
                {
                    tbRecv.Text += message + "
    ";
                }));
            }
    
            private void btnStart_Click(object sender, EventArgs e)
            {
                tcpClientSocket.Start();
            }
    
            private void btnSend_Click(object sender, EventArgs e)
            {
                string message = tbSend.Text.Trim();
                if (string.IsNullOrEmpty(message))
                    return;
    
                tcpClientSocket.SendAsync(message);
                tbSend.Text = "";
            }
        }
    

      

  • 相关阅读:
    关于xampp 集成开发包电脑重启mysql无法启动的问题
    ThinkPhP html原样入库
    java 获取图片大小(尺寸)
    xampps 不能配置非安装目录虚拟主机解决方案
    从0开始 java 网站开发(jsp)【1】
    Hello world!
    SpringMVC归纳-1(model数据模型与重定向传参技术)
    TTL与非门电路分析
    git入门手册:git的基本安装,本地库管理,远程上传
    实现简单的评论区功能
  • 原文地址:https://www.cnblogs.com/yaosj/p/11170887.html
Copyright © 2011-2022 走看看