天天看点

WinFormSocketTCP异步多线程实现断线重连完整源码附注释

TCP最主要的特点如下。

(1) 是面向连接的协议。

(2) 端到端的通信。每个TCP连接只能有两个端点,而且只能一对一通信,不能一点对多点直接通信。

(3) 高可靠性。通过TCP连接传送的数据,能保证数据无差错、不丢失、不重复地准确到达接收方,并且保证各数据到达的顺序与其发出的顺序相同

异步与同步的区别

同步工作方式是指利用TCP编写的程序执行到监听或接收语句时,在未完成工作(侦听到连接请求或收到对方发来的数据)前不再继续往下执行,线程处于阻塞状态,直到该语句完成相应的工作后才继续执行下一条语句。

异步工作方式是指程序执行到监听或接收语句时,不论工作是否完成,都会继续往下执行

完整源码如下:

public partial class MainForm : Form
    {
        private Socket socket;
        //Thread threadConnect;
        private int sendCount = 0;
        private int receiveCount = 0;
        /*------------定义与声明委托------------*/
        //显示消息
        private delegate void ShowMsgCallBack(string str);
        private ShowMsgCallBack showMsgCallBack;
        //显示状态
        private delegate void ShowStatusInfoCallBack(string str);
        private ShowStatusInfoCallBack showStatusInfoCallBack;
        //显示发送计数
        private delegate void ShowSendCountCallBack(string str);
        private ShowSendCountCallBack showSendCountCallBack;
        //显示接收计数
        private delegate void ShowReceiveCountCallBack(string str);
        private ShowReceiveCountCallBack showReceiveCountCallBack;
        //定时重连
        private delegate void ReConnectCallBack();
        private ReConnectCallBack reConnectCallBack;
        //异步调用(与要调用的方法具有相同签名)
        private delegate void ReceiveMsgDelegate(out string receiveMsg);
        private ReceiveMsgDelegate receiveMsgDelegate;
        private delegate void SendMsgDelegate(string sendMsg);
        private SendMsgDelegate sendMsgDelegate;
        /*------------定义与声明委托------------*/
        public MainForm()
        {
            InitializeComponent();
            /*----------实例化委托----------*/
            //显示消息
            showMsgCallBack = new ShowMsgCallBack(ShowMsg);
            //显示状态
            showStatusInfoCallBack = new ShowStatusInfoCallBack(ShowStatusInfo);
            //显示发送计数
            showSendCountCallBack = new ShowSendCountCallBack(ShowSendCount);
            //显示接收计数
            showReceiveCountCallBack = new ShowReceiveCountCallBack(ShowReceiveCount);
            //掉线后自动启动定时重连
            reConnectCallBack = new ReConnectCallBack(ReConnect);
            //接收消息
            receiveMsgDelegate = new ReceiveMsgDelegate(AsyncRcvMsg);
            //发送消息
            sendMsgDelegate = new SendMsgDelegate(AsyncSendMsg);
            /*----------实例化委托----------*/
            IPAddress[] localIP = Dns.GetHostAddresses("");
            txtIP.Text = localIP[0].ToString();
            txtIP.SelectAll();
            txtPort.Text = "9501";
            tbxReceiveCount.Text = sendCount.ToString();
            tbxReceiveCount.Text = receiveCount.ToString();

            
        }

        /*----------定义回调函数----------*/
        //显示消息
        private void ShowMsg(string str)
        {
            lstBoxMsg.Items.Add(str);
            lstBoxMsg.TopIndex = lstBoxMsg.Items.Count - 1;
        }

        //显示状态
        private void ShowStatusInfo(string str)
        {
            toolStripStatusInfo.Text = str;
        }

        //显示发送计数
        private void ShowSendCount(string str)
        {
            tbxSendCount.Text = str;
        }

        //显示接收计数
        private void ShowReceiveCount(string str)
        {
            tbxReceiveCount.Text = str;
        }

        private void ReConnect()
        {
            startConnectServer();
        }

        //异步接收
        private void AsyncRcvMsg(out string receiveMessage)
        {
            receiveMessage = null;
            try
            {
                Byte[] receiveByte = new Byte[64];
                socket.Receive(receiveByte, receiveByte.Length, 0);
                receiveMessage = Encoding.ASCII.GetString(receiveByte);
                if (receiveMessage.Trim('\0').Length == 0)
                {
                    if (socket != null)
                    {
                        socket.Close();
                    }
                    statusStripInfo.Invoke(showStatusInfoCallBack, "异步接收时连接断开!延时10秒后自动重新连接...");
                    //延时10秒后重新连接
                    DateTime now = DateTime.Now;
                    while (now.AddSeconds(10) > DateTime.Now) { }
                    Invoke(reConnectCallBack);  
                }
            }
            catch
            {
                if (socket != null)
                {
                    socket.Close();
                }
                statusStripInfo.Invoke(showStatusInfoCallBack, "异步接收时发生异常,连接断开!延时10秒后自动重新连接...");
                //延时10秒后重新连接
                DateTime now = DateTime.Now;
                while (now.AddSeconds(10) > DateTime.Now) { }
                Invoke(reConnectCallBack);  
            }
        }

        //异步发送
        private void AsyncSendMsg(string sendMessage)
        {
            try
            {
                Byte[] sendByte = new Byte[64];
                sendByte = Encoding.ASCII.GetBytes(sendMessage.ToCharArray());
                socket.Send(sendByte, sendByte.Length, 0);
            }
            catch
            {
                if (socket != null)
                {
                    socket.Close();
                }
                statusStripInfo.Invoke(showStatusInfoCallBack, "异步发送时异常,连接断开!");
            }
        }

        //定义回调函数
        private void btnConnect_Click(object sender, EventArgs e)
        {
            
            startConnectServer();
        }

        private void startConnectServer()
        {
            Thread threadConnect = new Thread(ConnectServerThread);
            threadConnect.Start();
            btnConnect.Enabled = false;
            btnSend.Enabled = true;
            btnDisConnect.Enabled = true;
        }

        //发起连接请求
        private void ConnectServerThread()
        {
            statusStripInfo.Invoke(showStatusInfoCallBack, "正在连接……"); 
            AsyncCallback requestcallback = new AsyncCallback(RequestCallBack);
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IAsyncResult result = socket.BeginConnect(IPAddress.Parse(txtIP.Text), int.Parse(txtPort.Text), requestcallback, socket);  
            while (result.IsCompleted == false)
            {
                Thread.Sleep(30);
            }
            
        }

        //回调函数,用于向服务进程发起连接请求
        private void RequestCallBack(IAsyncResult iar)
        {
            try
            {
                socket = (Socket)iar.AsyncState;
                socket.EndConnect(iar);
                if (socket != null)
                {
                    statusStripInfo.Invoke(showStatusInfoCallBack, "Socket连接成功!");
                    Thread threadReceive = new Thread(ReceiveMessage);
                    threadReceive.Start();
                }
            }
            catch
            {
                statusStripInfo.Invoke(showStatusInfoCallBack, "Socket连接时异常连接失败!延时10秒后自动重新连接...");
                //延时10秒后重新连接
                DateTime now = DateTime.Now;
                while (now.AddSeconds(10) > DateTime.Now) { }
                Invoke(reConnectCallBack);  
            }
        }

        //接收消息
        private void ReceiveMessage()
        {
            statusStripInfo.Invoke(showStatusInfoCallBack, "数据接收中...");
            string receiveString = null;
            while (true)
            {
                try
                {
                    IAsyncResult result = receiveMsgDelegate.BeginInvoke(out receiveString, null, null);    //异步接收
                    while (result.IsCompleted == false)
                    {
                        Thread.Sleep(50);
                        if (socket.Connected == false)
                            return;
                    }
                    receiveMsgDelegate.EndInvoke(out receiveString, result);
                    if (receiveString != null)
                    {
                        receiveCount++;
                        tbxReceiveCount.Invoke(showReceiveCountCallBack, receiveCount.ToString());   //显示接收计数
                        lstBoxMsg.Invoke(showMsgCallBack, receiveString);
                    }
                }
                catch
                {

                }
            } 
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            if (socket!=null && socket.Connected)
            {
                Thread threadSend = new Thread(new ParameterizedThreadStart(SendMessage));
                threadSend.Start(tbxMsg.Text);
            }
            else
                statusStripInfo.Invoke(showStatusInfoCallBack, "socket没有连接!");
        }

        //发送消息
        private void SendMessage(object state)
        {
            statusStripInfo.Invoke(showStatusInfoCallBack, "正在发送...");
            try
            {
                IAsyncResult result = sendMsgDelegate.BeginInvoke(state.ToString(), null, null);    //异步发送
                while (result.IsCompleted == false)
                {
                    Thread.Sleep(30);
                }
                sendMsgDelegate.EndInvoke(result);
                statusStripInfo.Invoke(showStatusInfoCallBack, "发送完毕!");
                sendCount++;
                tbxSendCount.Invoke(showSendCountCallBack, sendCount.ToString());      //显示发送计数
            }
            catch
            {
                statusStripInfo.Invoke(showStatusInfoCallBack, "数据发送时异常,发送失败!");
            }  
        }

        private void btnDisConnect_Click(object sender, EventArgs e)
        {
            if (socket != null)
            {
                socket.Close();
            }
            toolStripStatusInfo.Text = "连接断开!";
            btnConnect.Enabled = true;
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            lstBoxMsg.Items.Clear();
            sendCount = 0;
            receiveCount = 0;
            tbxSendCount.Text = sendCount.ToString();
            tbxReceiveCount.Text = receiveCount.ToString();
        }

    }
           

继续阅读