C# 异步Socket 及 窗体调用

1. 客户端和服务器Socket都使用 BeginXXX和EndXXX。

2. 设置一个Form1类型变量myForm1,当窗体Form1加载时将其this指针赋值给myForm1。
3. 当接收完毕后,调用Form1的成员函数 进行显示。需要注意,在Form1的成员函数中,如果需要用到Form1的控件,则需要使用委托。
4. 数据格式转化
(1)String 转 byte[ ]
         byte[ ] bytesToSend = Encoding.UTF8.GetBytes(textBoxSend.Text);
(2)byte[ ] 转 String
        string strText = Encoding.UTF8.GetString(recvBytes);
(3)String 转 byte[ ],如“123456”转为{0x12, 0x34, 0x56}
        private byte[] HexStringToBytes(string hexString)
        {
            string str = hexString;
            if(hexString.Length%2 != 0)
                str = hexString.Substring(0,hexString.Length - 1);
            int byteLength = str.Length / 2;
            byte[] bytes = new byte[byteLength];
            int bytesIndex = 0;
            for (int strIndex = 0; bytesIndex < bytes.Length; bytesIndex++, strIndex = strIndex + 2)
            {
                string hex = new String(new Char[]{str[strIndex], str[strIndex + 1]});
                byte[] b = BitConverter.GetBytes(int.Parse(hex,System.Globalization.NumberStyles.AllowHexSpecifier));
                bytes[bytesIndex] = b[0];
            }
            return bytes;
         }
(4)byte[ ] 转 String, 如{0x12, 0x34, 0x56}转为“123456”
        private string BytesToHexString(byte[] bytes) // 0xae00cf => "AE00CF "
        {
            string hexString = string.Empty;
            if (bytes != null)
            {
                StringBuilder strB = new StringBuilder();
 
                for (int i = 0; i < bytes.Length; i++)
                {
                    strB.Append(bytes[i].ToString("X2"));
                }
                hexString = strB.ToString();
            }
            return hexString;
        }
5. 客户端Connect函数
        public void Connect(EndPoint remoteEP)
        {
            Console.WriteLine("Connecting server...");
            try
            {
                if (client == null)
                    client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                if (!client.Connected)
                    client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
            }
            catch (System.Exception e)  //一般网络异常触发
            {
                Console.WriteLine("Net Error");
                if (client != null)
                {
                    client.Close();
                    client = null;  //在此需要赋值null
                }
            }  
        }
6. 服务器端
 (1)listen
        public void StartListening()
        {
            // Establish the local endpoint for the socket.
            IPEndPoint localEndPoint = GetIPEndPoint();
 
            // Create a TCP/IP socket.
            Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 
            // Bind the socket to the local endpoint and listen for incoming connections.
            try
            {
                listener.Bind(localEndPoint);
                listener.Listen(100);
                while (true)
                {
                    allDone.Reset();
                    // Start an asynchronous socket to listen for connections.
                    Console.WriteLine("Waiting for a connection...");
                    listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
                    // Wait until a connection is made before continuing.
                    allDone.WaitOne();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
            Console.WriteLine("\nPress ENTER to continue...");
            Console.Read();
        }
(2)AcceptCallback函数
当有客户端连接时触发,在此维护客户端Socket和其唯一标识Id的List
(3)当客户端Socket关闭 或出现网络异常时,ReadCallback方法中的
int bytesRead = handler.EndReceive(ar)会引发异常,在异常处理中关闭对应Socket并维护LIst
(4)send出现异常时,只要捕捉异常并进行相关提示就可以了,不用在此修改LIst
原文地址:https://www.cnblogs.com/ArRan/p/3067419.html