C# 的TCPClient 异步连接与异步读数据

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Threading;

namespace TcpClientTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        TcpClient tcp = null;
        NetworkStream workStream = null;

        private enum DataMode { Text, Hex }
        private char[] HexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'a', 'b', 'c', 'd', 'e', 'f' };
        private bool CharInArray(char aChar, char[] charArray)
        {
            return (Array.Exists<char>(charArray, delegate(char a) { return a == aChar; }));
        }

        /// <summary>

        /// 十六进制字符串转换字节数组

        /// </summary>

        /// <param name="s"></param>

        /// <returns></returns>

        private byte[] HexStringToByteArray(string s)
        {
            // s = s.Replace(" ", "");

            StringBuilder sb = new StringBuilder(s.Length);
            foreach (char aChar in s)
            {
                if (CharInArray(aChar, HexDigits))
                    sb.Append(aChar);
            }
            s = sb.ToString();
            int bufferlength;
            if ((s.Length % 2) == 1)
                bufferlength = s.Length / 2 + 1;
            else bufferlength = s.Length / 2;
            byte[] buffer = new byte[bufferlength];
            for (int i = 0; i < bufferlength - 1; i++)
                buffer[i] = (byte)Convert.ToByte(s.Substring(* i, 2), 16);
            if (bufferlength > 0)
                buffer[bufferlength - 1] = (byte)Convert.ToByte(s.Substring(* (bufferlength - 1), (s.Length % 2 == 1 ? 1 : 2)), 16);
            return buffer;
        }

        /// <summary>

        /// 字节数组转换十六进制字符串

        /// </summary>

        /// <param name="data"></param>

        /// <returns></returns>

        private string ByteArrayToHexString(byte[] data)
        {
            StringBuilder sb = new StringBuilder(data.Length * 3);
            foreach (byte b in data)
                sb.Append(Convert.ToString(b, 16).PadLeft(2, '0').PadRight(3, ' '));
            return sb.ToString().ToUpper();
        }

        /// <summary>

        /// 当前接收模式

        /// </summary>

        private DataMode CurrentReceiveDataMode
        {
            get
            {
                return (chkHexReceive.Checked) ? DataMode.Hex : DataMode.Text;
            }
            set
            {
                chkHexReceive.Checked = (value == DataMode.Text);
            }
        }

        /// <summary>

        /// 当前发送模式

        /// </summary>

        private DataMode CurrentSendDataMode
        {
            get
            {
                return (chkHexSend.Checked) ? DataMode.Hex : DataMode.Text;
            }
            set
            {
                chkHexSend.Checked = (value == DataMode.Text);
            }
        }

        /// <summary>

        /// 发送数据

        /// </summary>

        private void SendData()
        {
            if (workStream != null)
            {
                byte[] data;
                if (CurrentSendDataMode == DataMode.Text)
                {
                    data = Encoding.ASCII.GetBytes(rtfSend.Text);
                }
                else
                {
                    // 转换用户十六进制数据到字节数组

                    data = HexStringToByteArray(rtfSend.Text);
                }
                workStream.Write(data,0,data.Length);
            }
        }

        delegate void SetTextCallback(string text);
        delegate void SetControl();
        delegate void GetData(byte[] data);

        /// <summary>

        /// 异步接收数据

        /// </summary>

        /// <param name="data"></param>

        private void OnGetData(byte[] data)
        {
            string sdata;
            if (CurrentReceiveDataMode == DataMode.Text)
            {
                sdata = new string(Encoding.UTF8.GetChars(data));
            }
            else
            {
                sdata = ByteArrayToHexString(data);
            }

            rtfReceive.Invoke(new EventHandler(delegate
            {
                rtfReceive.AppendText(sdata);
            }));
        }

        /// <summary>

        /// 异步设置Log

        /// </summary>

        /// <param name="text"></param>

        private void SetText(string text)
        {
            if (rtfLog.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(SetText);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                rtfLog.AppendText(text + Environment.NewLine);
            }
        }

        public ManualResetEvent connectDone = new ManualResetEvent(false);

        /// <summary>

        /// 异步连接的回调函数

        /// </summary>

        /// <param name="ar"></param>

        private void ConnectCallback(IAsyncResult ar)
        {
            connectDone.Set();
            TcpClient t = (TcpClient)ar.AsyncState;
            try
            {
                if (t.Connected)
                {
                    SetText("连接成功");
                    t.EndConnect(ar);
                    SetText("连接线程完成");
                }
                else
                {
                    SetText("连接失败");
                    t.EndConnect(ar);
                }
                
            }
            catch (SocketException se)
            {
                SetText("连接发生错误ConnCallBack.......:"+se.Message);
            }
        }

        /// <summary>

        /// 异步连接

        /// </summary>

        private void Connect()
        {
            if ((tcp == null) || (!tcp.Connected))
            {
                try
                {
                    tcp = new TcpClient();
                    tcp.ReceiveTimeout = 10;


                    connectDone.Reset();

                    SetText("Establishing Connection to " + txtIP.Text);

                    tcp.BeginConnect(txtIP.Text, (int) numPort.Value,
                        new AsyncCallback(ConnectCallback), tcp);

                    connectDone.WaitOne();

                    if ((tcp != null) && (tcp.Connected))
                    {
                        workStream = tcp.GetStream();

                        SetText("Connection established");

                        asyncread(tcp);
                    }
                }
                catch (Exception se)
                {
                    rtfLog.AppendText(se.Message+" Conn......."+Environment.NewLine);
                }
            }
        }

        /// <summary>

        /// 断开连接

        /// </summary>

        private void DisConnect()
        {
            if ((tcp != null) && (tcp.Connected))
            {
                workStream.Close();
                tcp.Close();
            }
        }

        /// <summary>

        /// 设置控件状态

        /// </summary>

        private void setBtnStatus()
        {
            if ((btnConnect.InvokeRequired) || (btnSend.InvokeRequired))
            {
                this.Invoke(new SetControl(setBtnStatus));
            }
            else
            {
                int con = ((tcp == null) || (!tcp.Connected)) ? 0 : 1;
                string[] constr = { "连接", "断开" };
                bool[] btnEnabled = { false, true };

                btnConnect.Text = constr[con];
                btnSend.Enabled = btnEnabled[con];
            }
        }

        /// <summary>

        /// 连接按钮

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void btnConnect_Click(object sender, EventArgs e)
        {
            if ((tcp != null) && (tcp.Connected))
            {
                DisConnect();
            }
            else
            {
                Connect();
            }
            setBtnStatus();
        }

        /// <summary>

        /// 发送数据按钮

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void btnSend_Click(object sender, EventArgs e)
        {
            try
            {
                SendData();
            }
            catch (Exception se)
            {
                rtfLog.AppendText(se.Message+Environment.NewLine);
            }
        }

        /// <summary>

        /// 异步读TCP数据

        /// </summary>

        /// <param name="sock"></param>

        private void asyncread(TcpClient sock)
        {
            StateObject state = new StateObject();
            state.client = sock;
            NetworkStream stream = sock.GetStream();

            if (stream.CanRead)
            {
                try
                {
                    IAsyncResult ar = stream.BeginRead(state.buffer, 0, StateObject.BufferSize,
                            new AsyncCallback(TCPReadCallBack), state);
                }
                catch (Exception e)
                {
                    SetText("Network IO problem " + e.ToString());
                }
            }
        }

        /// <summary>

        /// TCP读数据的回调函数

        /// </summary>

        /// <param name="ar"></param>

        private void TCPReadCallBack(IAsyncResult ar)
        {
            StateObject state = (StateObject)ar.AsyncState;
            //主动断开时

            if ((state.client == null) || (!state.client.Connected))
                return;
            int numberOfBytesRead;
            NetworkStream mas = state.client.GetStream();
            string type = null;

            numberOfBytesRead = mas.EndRead(ar);
            state.totalBytesRead += numberOfBytesRead;

            SetText("Bytes read ------ "+ numberOfBytesRead.ToString());
            if (numberOfBytesRead > 0)
            {
                byte[] dd = new byte[numberOfBytesRead];
                Array.Copy(state.buffer,0,dd,0,numberOfBytesRead);
                OnGetData(dd);
                mas.BeginRead(state.buffer, 0, StateObject.BufferSize,
                        new AsyncCallback(TCPReadCallBack), state);
            }
            else
            {
                //被动断开时 

                mas.Close();
                state.client.Close();
                SetText("Bytes read ------ "+ numberOfBytesRead.ToString());
                SetText("不读了");
                mas = null;
                state = null;

                setBtnStatus();
            }
        }

    }

    internal class StateObject
    {
        public TcpClient client = null;
        public int totalBytesRead = 0;
        public const int BufferSize = 1024;
        public string readType = null;
        public byte[] buffer = new byte[BufferSize];
        public StringBuilder messageBuffer = new StringBuilder();
    }

}


Form1.Design.cs

 

namespace  TcpClientTest
{
    
partial class Form1
    
{
        
/// <summary>
        
/// 必需的设计器变量。
        
/// </summary>

        private System.ComponentModel.IContainer components = null;

        
/// <summary>
        
/// 清理所有正在使用的资源。
        
/// </summary>
        
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>

        protected override void Dispose(bool disposing)
        
{
            
if (disposing && (components != null))
            
{
                components.Dispose();
            }

            
base.Dispose(disposing);
        }


        
#region Windows 窗体设计器生成的代码

        
/// <summary>
        
/// 设计器支持所需的方法 - 不要
        
/// 使用代码编辑器修改此方法的内容。
        
/// </summary>

        private void InitializeComponent()
        
{
            
this.txtIP = new System.Windows.Forms.TextBox();
            
this.numPort = new System.Windows.Forms.NumericUpDown();
            
this.label1 = new System.Windows.Forms.Label();
            
this.label2 = new System.Windows.Forms.Label();
            
this.btnConnect = new System.Windows.Forms.Button();
            
this.chkHexReceive = new System.Windows.Forms.CheckBox();
            
this.chkHexSend = new System.Windows.Forms.CheckBox();
            
this.rtfSend = new System.Windows.Forms.RichTextBox();
            
this.rtfReceive = new System.Windows.Forms.RichTextBox();
            
this.btnSend = new System.Windows.Forms.Button();
            
this.rtfLog = new System.Windows.Forms.RichTextBox();
            ((System.ComponentModel.ISupportInitialize)(
this.numPort)).BeginInit();
            
this.SuspendLayout();
            
// 
            
// txtIP
            
// 
            this.txtIP.Location = new System.Drawing.Point(5812);
            
this.txtIP.Name = "txtIP";
            
this.txtIP.Size = new System.Drawing.Size(14221);
            
this.txtIP.TabIndex = 0;
            
this.txtIP.Text = "127.0.0.1";
            
// 
            
// numPort
            
// 
            this.numPort.Location = new System.Drawing.Point(5839);
            
this.numPort.Maximum = new decimal(new int[] {
            
65535,
            
0,
            
0,
            
0}
);
            
this.numPort.Name = "numPort";
            
this.numPort.Size = new System.Drawing.Size(14221);
            
this.numPort.TabIndex = 1;
            
this.numPort.Value = new decimal(new int[] {
            
9099,
            
0,
            
0,
            
0}
);
            
// 
            
// label1
            
// 
            this.label1.AutoSize = true;
            
this.label1.Location = new System.Drawing.Point(1116);
            
this.label1.Name = "label1";
            
this.label1.Size = new System.Drawing.Size(1712);
            
this.label1.TabIndex = 2;
            
this.label1.Text = "IP";
            
// 
            
// label2
            
// 
            this.label2.AutoSize = true;
            
this.label2.Location = new System.Drawing.Point(1143);
            
this.label2.Name = "label2";
            
this.label2.Size = new System.Drawing.Size(2912);
            
this.label2.TabIndex = 3;
            
this.label2.Text = "Port";
            
// 
            
// btnConnect
            
// 
            this.btnConnect.Location = new System.Drawing.Point(1466);
            
this.btnConnect.Name = "btnConnect";
            
this.btnConnect.Size = new System.Drawing.Size(7523);
            
this.btnConnect.TabIndex = 4;
            
this.btnConnect.Text = "连接";
            
this.btnConnect.UseVisualStyleBackColor = true;
            
this.btnConnect.Click += new System.EventHandler(this.btnConnect_Click);
            
// 
            
// chkHexReceive
            
// 
            this.chkHexReceive.AutoSize = true;
            
this.chkHexReceive.Location = new System.Drawing.Point(14100);
            
this.chkHexReceive.Name = "chkHexReceive";
            
this.chkHexReceive.Size = new System.Drawing.Size(9616);
            
this.chkHexReceive.TabIndex = 5;
            
this.chkHexReceive.Text = "十六进制接收";
            
this.chkHexReceive.UseVisualStyleBackColor = true;
            
// 
            
// chkHexSend
            
// 
            this.chkHexSend.AutoSize = true;
            
this.chkHexSend.Location = new System.Drawing.Point(109100);
            
this.chkHexSend.Name = "chkHexSend";
            
this.chkHexSend.Size = new System.Drawing.Size(9616);
            
this.chkHexSend.TabIndex = 6;
            
this.chkHexSend.Text = "十六进制发送";
            
this.chkHexSend.UseVisualStyleBackColor = true;
            
// 
            
// rtfSend
            
// 
            this.rtfSend.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        
| System.Windows.Forms.AnchorStyles.Right)));
            
this.rtfSend.Location = new System.Drawing.Point(21112);
            
this.rtfSend.Name = "rtfSend";
            
this.rtfSend.Size = new System.Drawing.Size(45396);
            
this.rtfSend.TabIndex = 7;
            
this.rtfSend.Text = "";
            
// 
            
// rtfReceive
            
// 
            this.rtfReceive.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        
| System.Windows.Forms.AnchorStyles.Left)
                        
| System.Windows.Forms.AnchorStyles.Right)));
            
this.rtfReceive.Location = new System.Drawing.Point(211122);
            
this.rtfReceive.Name = "rtfReceive";
            
this.rtfReceive.Size = new System.Drawing.Size(453327);
            
this.rtfReceive.TabIndex = 8;
            
this.rtfReceive.Text = "";
            
// 
            
// btnSend
            
// 
            this.btnSend.Enabled = false;
            
this.btnSend.Location = new System.Drawing.Point(13066);
            
this.btnSend.Name = "btnSend";
            
this.btnSend.Size = new System.Drawing.Size(7523);
            
this.btnSend.TabIndex = 9;
            
this.btnSend.Text = "发送";
            
this.btnSend.UseVisualStyleBackColor = true;
            
this.btnSend.Click += new System.EventHandler(this.btnSend_Click);
            
// 
            
// rtfLog
            
// 
            this.rtfLog.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        
| System.Windows.Forms.AnchorStyles.Left)));
            
this.rtfLog.Location = new System.Drawing.Point(12122);
            
this.rtfLog.Name = "rtfLog";
            
this.rtfLog.Size = new System.Drawing.Size(193327);
            
this.rtfLog.TabIndex = 10;
            
this.rtfLog.Text = "";
            
// 
            
// Form1
            
// 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            
this.ClientSize = new System.Drawing.Size(676461);
            
this.Controls.Add(this.rtfLog);
            
this.Controls.Add(this.btnSend);
            
this.Controls.Add(this.rtfReceive);
            
this.Controls.Add(this.rtfSend);
            
this.Controls.Add(this.chkHexSend);
            
this.Controls.Add(this.chkHexReceive);
            
this.Controls.Add(this.btnConnect);
            
this.Controls.Add(this.label2);
            
this.Controls.Add(this.label1);
            
this.Controls.Add(this.numPort);
            
this.Controls.Add(this.txtIP);
            
this.Name = "Form1";
            
this.Text = "Form1";
            ((System.ComponentModel.ISupportInitialize)(
this.numPort)).EndInit();
            
this.ResumeLayout(false);
            
this.PerformLayout();

        }


        
#endregion


        
private System.Windows.Forms.TextBox txtIP;
        
private System.Windows.Forms.NumericUpDown numPort;
        
private System.Windows.Forms.Label label1;
        
private System.Windows.Forms.Label label2;
        
private System.Windows.Forms.Button btnConnect;
        
private System.Windows.Forms.CheckBox chkHexReceive;
        
private System.Windows.Forms.CheckBox chkHexSend;
        
private System.Windows.Forms.RichTextBox rtfSend;
        
private System.Windows.Forms.RichTextBox rtfReceive;
        
private System.Windows.Forms.Button btnSend;
        
private System.Windows.Forms.RichTextBox rtfLog;
    }

}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值