c# winform 實現客戶端和服務器端互相交互


服務器端的代碼

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {


        public Form1()
        {
            InitializeComponent();
        }



        private void tbPortNum_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar > 31)
                if (e.KeyChar < 48 || e.KeyChar > 57)
                {
                    MessageBox.Show("輸入非法字符!", "警告!");
                    tbPortNum.Text = "";
                }
            if (tbPortNum.Text != "")
            {
                btCreServer.Enabled = true;
            }
        }

        // private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
        //{

        //}

        //獲取本機的IP
        //獲取本機的IP
        public Boolean SocketIsConnected(Socket soc)
        {
            Boolean isconnected = false;
            try
            {

                soc.Send(System.Text.Encoding.Default.GetBytes("hello!"));
                isconnected = true;
            }

            catch
            {
                isconnected = false;
            }

            return isconnected;

        }



        public string GetLocalIP()
        {

            IPAddress[] AddressList = Dns.GetHostAddresses(Dns.GetHostName());
            return AddressList[1].ToString();


        }




        Socket sock;          //定義一個Socket類的對象 (默認為protected)
        Thread th;             //定義一個Thread類的對象
        Socket newSock;
        //BackgroundWorker bgw = new BackgroundWorker();
        private void BeginListen()               //Socket監聽函數, 等下作為創建新線程的參數
        {

            IPAddress serverIp = IPAddress.Parse(GetLocalIP());         //調用本類靜態函數GetLocalIP得到本機IPAddress.
            IPEndPoint iep = new IPEndPoint(serverIp, Convert.ToInt32(tbPortNum.Text));    //本地終結點
            sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);   //實例化內成員sock
            // Boolean BuildSocketAccept=false ;
            // bgw.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
            //bgw.RunWorkerAsync(bs);
            //this.label1.Text = iep.ToString();

            sock.Bind(iep);                                  //Socket類的一個重要函數, 綁定一個IP,
            while (true)                     //這里弄了個死循環來監聽端口, 有人會問死循環了,那程序不卡住了, 注意這只是個類, 這里還沒有main函數呢.
            {
                try
                {
                    sock.Listen(10);             //好了,sock綁定了本地終結點就可以開始監聽了,5表示最大連接數為5
                    newSock = sock.Accept();     //這里又有Socket類的一個重要的方法:Accept, 該方法接受來自外面的Socket連接請求, 並返回一個Socket套接字, 這個套接字就開始處理這一個client與Server之間的對話
                    BackgroundWorker bgwClintIP = new BackgroundWorker();
                    bgwClintIP.DoWork += new DoWorkEventHandler(bgWorker_DoWorkClintIP);
                    //bgwClintIP.RunWorkerAsync(System.Text.Encoding.Default.GetBytes(newSock.RemoteEndPoint.ToString()));
                    if (!SocketIsConnected(newSock))
                    {
                        MessageBox.Show("連接已斷開!");
                        break;

                    }
                    while (true)
                    {
                        try
                        {
                            Byte[] byteMessage = new Byte[100]; //存放消息的字節數組緩沖區, 注意數組表示方法,和C不同的.
                            newSock.Receive(byteMessage); //接受client發送過來的數據保存到緩沖區.
                            BackgroundWorker bgw = new BackgroundWorker();
                            bgw.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
                            bgw.RunWorkerAsync(byteMessage);
                        }
                        catch
                        {

                        }

                    }

                  
                }
                catch (SocketException se)              //捕捉異常,
                {
                    MessageBox.Show(se.ToString());
                    //lbState.Text = se.ToString();       //將其顯示出來, 在此亦可以自定義錯誤.
                }
            }
        }
        private void bgWorker_DoWorkClintIP(object sender, DoWorkEventArgs e)
        {
            byte[] bs = (byte[])e.Argument;
            string r1 = Encoding.Default.GetString(bs);
            //RevDataList.BeginInvoke(new System.EventHandler(ShowGetByte), r1);
            this.BeginInvoke(new System.EventHandler(AddClintIPPage), r1);

        }
        private void AddClintIPPage(object o, System.EventArgs e)
        {


            lbClintIP.Text = o.ToString();
            lbState.Text = "已建立連接";
            tbRecMSG.AppendText("\r\n" + "建立連接:" + o.ToString());

        }
        private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            byte[] bs = (byte[])e.Argument;
            string r1 = Encoding.Default.GetString(bs);
            //RevDataList.BeginInvoke(new System.EventHandler(ShowGetByte), r1);
            this.BeginInvoke(new System.EventHandler(ShowGetByte), r1);
        }
        private void ShowGetByte(object o, System.EventArgs e)
        {


            tbRecMSG.AppendText("\r\n" + lbClintIP.Text + "客戶端:" + o.ToString());

        }



        private void btCreServer_Click(object sender, EventArgs e)
        {

            if (btCreServer.Text == "設立服務器")
            {
                btCreServer.Text = "關閉服務器";
                tbPortNum.Enabled = false;
                lbLocalIP.Text = "本地IP:" + GetLocalIP();

                try
                {
                    th = new Thread(new ThreadStart(BeginListen));          //創建一個新的線程專門用於處理監聽,這句話可以分開寫的,比如: ThreadStart ts=new ThreadStart(BeginListen); th=new Thread (ts); 不過要注意, ThreadStart的構造函數的參數一定要是無參數的函數. 在此函數名其實就是其指針, 這里是委托嗎?
                    th.Start();                            //啟動線程
                    lbState.Text = "狀態:正在監聽";
                }
                catch (SocketException se)           //處理異常
                {
                    MessageBox.Show(se.Message, "出現問題", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                catch (ArgumentNullException ae)   //參數為空異常
                {
                    lbState.Text = "參數錯誤";
                    MessageBox.Show(ae.Message, "錯誤", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }

            else
            {
                btCreServer.Text = "建立服務器";
                tbPortNum.Enabled = true;
                sock.Close();                     //關閉套接字
                th.Abort();                         //終止監聽線程
                lbState.Text = "狀態:停止監聽";
            }
        }

        private void btSendMSG_Click(object sender, EventArgs e)
        {

            if (newSock == null)
                MessageBox.Show("尚未建立連接,發送失敗!");
            else if (tbSendMSG.Text == "")
                MessageBox.Show("輸入為空,發送失敗!");
            else
            {
                try
                {

                    newSock.Send(System.Text.Encoding.Default.GetBytes(tbSendMSG.Text));
                    tbRecMSG.AppendText("\r\n" + "服務器端:" + tbSendMSG.Text);
                }

                catch (ArgumentNullException ae)
                {
                    MessageBox.Show(ae.Message, "參數為空", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
                }
                catch (SocketException se)
                {
                    MessageBox.Show(se.Message, "出現問題", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            tbSendMSG.Text = "";
        }

        private void tbPortNum_TextChanged(object sender, EventArgs e)
        {

        } 

        private void tbRecMSG_TextChanged(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            tbRecMSG.Text = "";
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

    }

}

 

客戶端的代碼

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

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

        public Boolean SocketIsConnected(Socket soc)
        {
            Boolean isconnected = false;
            try
            {

                soc.Send(System.Text.Encoding.Default.GetBytes("$"));
                isconnected = true;
            }

            catch
            {
                isconnected = false;
            }

            return isconnected;

        }

        private Socket sock;          //定義一個Socket類的對象 (默認為protected)
        Thread th;             //定義一個Thread類的對象
        //Socket newSock;

        private void BeginListen()               //Socket監聽函數, 等下作為創建新線程的參數
        {
            int Port = int.Parse(textPort.Text);
            IPAddress ip = IPAddress.Parse(textIp.Text);         //調用本類靜態函數GetLocalIP得到本機IPAddress.
            IPEndPoint ipp = new IPEndPoint(ip, Port);
           
            //IPEndPoint iep = new IPEndPoint(serverIp, Convert.ToInt32(tbPortNum.Text));    //本地終結點
            sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);   //實例化內成員sock
            sock.Connect(ipp);    //連接服務器

            // if (!SocketIsConnected(sock))
            //{
            //    lbState.Text="連接已斷開!";
            //    return;
            //}
            //else
            //{
            //    //lbState.Text = "也連接到服務器!";

            //}
           do
           { 
                    Byte[] byteMessage = new Byte[100]; //存放消息的字節數組緩沖區, 注意數組表示方法,和C不同的.
                    sock.Receive(byteMessage); //接受Server發送過來的數據保存到緩沖區.
                    BackgroundWorker bgw = new BackgroundWorker();
                    bgw.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
                    bgw.RunWorkerAsync(byteMessage);
         
           }while(true);
                       
        }

      
        private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            byte[] bs = (byte[])e.Argument;
            string r1 = Encoding.Default.GetString(bs);
            //RevDataList.BeginInvoke(new System.EventHandler(ShowGetByte), r1);
            this.BeginInvoke(new System.EventHandler(ShowGetByte), r1);
        }
        private void ShowGetByte(object o, System.EventArgs e)
        {

            //textRec.AppendText("\r\n" + lbClintIP.Text + 'Server:' + o.ToString());
            textRec.AppendText("\r\n" + "服務器端:" + o.ToString());

        }




        //當點擊連接服務器的時候
        private void btConnectServer_Click(object sender, EventArgs e)
        {
            if (btConnectServer.Text == "連接服務器")
            {
                btConnectServer.Text = "斷開連接";
                textIp.Enabled = false;
                textPort.Enabled = false;
                //lbLocalIP.Text = "本地IP:" + GetLocalIP();

                try
                {
                    th = new Thread(new ThreadStart(BeginListen));          //創建一個新的線程專門用於處理監聽,這句話可以分開寫的,比如: ThreadStart ts=new ThreadStart(BeginListen); th=new Thread (ts); 不過要注意, ThreadStart的構造函數的參數一定要是無參數的函數. 在此函數名其實就是其指針, 這里是委托嗎?
                    th.Start();                            //啟動線程

                }
                catch (SocketException se)           //處理異常
                {
                    MessageBox.Show(se.Message, "出現問題", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                catch (ArgumentNullException ae)   //參數為空異常
                {
                    lbState.Text = "參數錯誤";
                    MessageBox.Show(ae.Message, "錯誤", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
            else
            {
                btConnectServer.Text = "連接服務器";
                textIp.Enabled = true;
                textPort.Enabled = true;
                sock.Close();                     //關閉套接字
                th.Abort();                         //終止監聽線程
               
            }
        }

        private void btSend_Click(object sender, EventArgs e)
        {
            if (sock == null)
                MessageBox.Show("尚未建立連接,發送失敗!");
            else if (textSend.Text == "")
                MessageBox.Show("輸入為空,發送失敗!");
            else
            {
                try
                {

                    sock.Send(System.Text.Encoding.Default.GetBytes(textSend.Text));
                    textRec.AppendText("\r\n" + "客戶端:" + textSend.Text);
                }

                catch (ArgumentNullException ae)
                {
                    MessageBox.Show(ae.Message, "參數為空", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
                }
                catch (SocketException se)
                {
                    MessageBox.Show(se.Message, "出現問題", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            textSend.Text = "";
        }

        private void textIp_TextChanged(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            textRec.Text = "";
        }

    
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM