應用程式在網路上通訊的實現(C#)

來源:互聯網
上載者:User

最近趕活,連續在網上抄了好幾次代碼,很讓我覺得有點不好意思,因為我一般不大喜歡發程式碼片段,覺得沒啥意思。不過最近這個想法有所改變,大家互相抄抄有助於提高生產率嘛。。。

以下發一個通訊類,如需引用,請註明作者,謝謝。

/// <summary>/// Author:Scott.Yan/// Blog:http://www.cnblogs.com/moosdau/// </summary>public class Communication{    /// <summary>    /// Get the first valid IPV4 address    /// </summary>    /// <returns></returns>    public static System.Net.IPAddress GetLocalIP()    {        var host = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName());        if (host.AddressList.Length < 1)            throw new Exception("Can't find any valid IP address.");        System.Net.IPAddress myIP = null;        foreach (var p in host.AddressList)        {            if (!p.IsIPv6LinkLocal)            {                myIP = p;                break;            }        }        if (myIP == null)            throw new Exception("Can't find any valid IPV4 address.");        return myIP;    }    /// <summary>    /// Communication based on TCP by Scott.Yan    /// </summary>    public class TCPManage    {        private Action<string> DgGetMsg;        private System.Windows.Forms.Control Owner;        /// <summary>        /// indicate whether the thread should stop listening        /// </summary>        private bool IsListening = true;        /// <summary>        /// 1123 is the birthday of Scott.Yan who is the author of this class        /// </summary>        private const int TCPPort = 1123;        private System.Threading.Thread thTCPListener;        /// <summary>        /// send message to others        /// </summary>        /// <param name="destinationIP">the destination ip ,e.g.,192.168.1.1</param>        /// <param name="msg">message you want to send</param>        public void SendMessage(string destinationIP, string msg)        {            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(msg);            var destIP = System.Net.IPAddress.Parse(destinationIP);            var myIP = Communication.GetLocalIP();            var epDest = new System.Net.IPEndPoint(destIP, TCPPort);            var dpLocal = new System.Net.IPEndPoint(myIP, TCPPort);            var tcpClient = new System.Net.Sockets.TcpClient();            tcpClient.Connect(epDest);            var netStream = tcpClient.GetStream();            if (netStream.CanWrite)                netStream.Write(buffer, 0, buffer.Length);        }        /// <summary>        /// call this method to start listening        /// <param name="owner">formally you should pass "this"</param>        /// <param name="dgGetMsg">a delegate handles when receive a message</param>        /// </summary>                    public void StartListen(System.Windows.Forms.Control owner, Action<string> dgGetMsg)        {            IsListening = true;            Owner = owner;            DgGetMsg = dgGetMsg;            thTCPListener = new System.Threading.Thread(ListenHandler);            thTCPListener.Start();        }        /// <summary>        /// call this method to stop listening        /// </summary>        public void StopListen()        {            IsListening = false;        }        private void ListenHandler()        {            var myIP = Communication.GetLocalIP();            var epLocal = new System.Net.IPEndPoint(myIP, TCPPort);            var tcpListener = new System.Net.Sockets.TcpListener(epLocal);            tcpListener.Start();            while (IsListening)            {                System.Threading.Thread.Sleep(1000);                if (tcpListener.Pending())                {                    var tcpClient = tcpListener.AcceptTcpClient();                    var netStream = tcpClient.GetStream();                    var buffer = new byte[1024];                    if (!netStream.DataAvailable)                        continue;                    List<byte> bufferTotal = new List<byte>();                    while (netStream.DataAvailable)                    {                        netStream.Read(buffer, 0, 1024);                        bufferTotal.AddRange(buffer);                    }                    tcpClient.Close();                    netStream.Close();                    var receive = System.Text.Encoding.UTF8.GetString(bufferTotal.ToArray());                    Owner.Invoke(DgGetMsg, receive);                }            }            tcpListener.Stop();        }    }    /// <summary>    /// Communication based on UDP by Scott.Yan    /// </summary>    public class UDPManage    {        /// <summary>        /// this is a group address        /// </summary>        private System.Net.IPAddress GroupIP = System.Net.IPAddress.Parse("224.0.0.2");        /// <summary>        /// the birthday of Scott.Yan in Chinese lunar calendar        /// </summary>        private const int UDPPort = 1019;        private System.Net.Sockets.UdpClient UdpClient;        private System.Threading.Thread thUDPListener;        private bool IsListening = true;        private System.Windows.Forms.Control Owner;        private Action<string> DgGetMsg;        /// <summary>        /// broadcast a message to others        /// </summary>        /// <param name="msg"></param>        public void Broadcast(string msg)        {            var epGroup = new System.Net.IPEndPoint(GroupIP, UDPPort);            var buffer = System.Text.Encoding.UTF8.GetBytes(msg);            UdpClient.Send(buffer, buffer.Length, epGroup);        }        /// <summary>        /// listen to the group         /// </summary>        /// <param name="owner">"this" in most case</param>        /// <param name="dgGetMsg">handles message arriving</param>        public void StartListen(System.Windows.Forms.Control owner, Action<string> dgGetMsg)        {            Owner = owner;            DgGetMsg = dgGetMsg;            IsListening = true;            UdpClient = new System.Net.Sockets.UdpClient(UDPPort);            UdpClient.JoinMulticastGroup(GroupIP);            thUDPListener = new System.Threading.Thread(ListenHandler);            thUDPListener.Start();        }        /// <summary>        /// stop listen        /// </summary>        public void StopListen()        {            IsListening = false;            UdpClient.DropMulticastGroup(GroupIP);            UdpClient.Close();        }        private void ListenHandler()        {            var epGroup = new System.Net.IPEndPoint(System.Net.IPAddress.Any, UDPPort);            byte[] buffer = null;            while (IsListening)            {                System.Threading.Thread.Sleep(1000);                try { buffer = UdpClient.Receive(ref epGroup); }                catch { }                if (buffer == null || buffer.Length < 1)                    continue;                var msg = System.Text.Encoding.UTF8.GetString(buffer);                if (msg.Length > 0)                    Owner.Invoke(DgGetMsg, msg);            }        }    }}

說明:

這個類包含兩個子類,TCPManage和UDPManage,分別處理TCP和UDP兩種協議。TCP用於點對點,UDP用於組內多播。由於實際網路情況複雜多變,應多加try和檢查,但是我偷懶,就不做了,如果要在項目中引用本類,而你也和我一樣懶得去修改它的話,應在調用每一個方法時加try。

另外,當接收資料時我為簡單起見沒有分段,所以只能用於處理小資料量,而且只能傳輸字串。(要實現其它,在這個基礎上稍做處理即可)這個類的目的非常明確,就像QQ一樣在網路上傳輸不太長的字串,所以它的介面非常簡單,調用起來非常容易。但同時也犧牲了自訂的空間,不過我認為這一般不是個問題,封裝的目的就是要簡單。

以下是測試代碼,同時也示範了如何使用這個類。

建立一個windows form項目,在上面放兩個文字框(它們最好夠大),上面一個叫txt1,用於儲存訊息曆史,下面一個叫txt2,用於向別人發送(就像qq聊天視窗一樣),最下面放個按鈕, 如所示:


然後在字碼頁中:

    public partial class Form1 : Form    {        public Form1()        {            InitializeComponent();        }        Communication.UDPManage udpMng;        Communication.TCPManage tcpMng;        private void Form1_Load(object sender, EventArgs e)        {            //tcpMng = new Communication.TCPManage();            //tcpMng.StartListen(this, SetText);            udpMng = new Communication.UDPManage();            udpMng.StartListen(this, SetText);        }        private void Form1_FormClosing(object sender, FormClosingEventArgs e)        {            //tcpMng.StopListen();            udpMng.StopListen();        }        private void SetText(string val)        {            txt1.Text += val + System.Environment.NewLine;        }        private void button1_Click(object sender, EventArgs e)        {            //tcpMng.SendMessage("192.168.1.2", txt2.Text);            udpMng.Broadcast(txt2.Text);        }    }

 

以上代碼同時示範了tcp和udp兩個類的使用方法,其中tcp的部分注釋掉了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.