1. 程式人生 > >【C#】-區域網下用Socket實現通訊

【C#】-區域網下用Socket實現通訊

前言

聽起區域網下聊天是不是很難,很高大上的樣子,怎麼樣讓兩臺電腦,在同一區域網下實現聊天呢,先說一下思路吧,一會直接上程式碼。

1. 首先我們先要建立一個伺服器,也就是說兩臺電腦有一臺要當著伺服器,供客戶端連結。
2. 伺服器建立好,伺服器還要時時刻刻的接受客戶端的連結。
3. 客戶端連線上之後,伺服器還要時時刻刻接受客戶端發來的資訊。
4. 客戶端傳送訊息,當然要以位元組的形式傳給伺服器,這中間就會有一個轉化的過程。
5. 當然伺服器和客戶端都要有接受傳送訊息
6. 最後把客戶端發來訊息追加上去

思路就是這個樣子聽起來好像還可以哈!

建立伺服器

            //Socket伺服器端的邏輯
            //1、建立Socket物件
            //第一個引數設定網路定址的協議   第二個引數設定資料傳輸的方式  第三個引數資料設定通訊的協議
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
			
			//追加到文字
            this.txtLog.Text = "建立伺服器端Socket物件\r\n" + this.txtLog.Text;

            //2、繫結IP和埠
            IPAddress ip = IPAddress.Parse("192.168.20.240");
            IPEndPoint ipEndpoint = new IPEndPoint(Administrator.frmAdministratorMain.ip, int.Parse("51000"));
            Administrator.frmAdministratorMain.serverSocket.Bind(Administrator.frmAdministratorMain.ipEndpoint);

            serverSocket.Bind(ipEndpoint);

            3、開啟偵聽
            Administrator.frmAdministratorMain.serverSocket.Listen(10);  //等待連結的佇列

            4、開始接受客戶端的連結
            this.txtLog.Text = "開始接受客戶端連結\r\n" + this.txtLog.Text;

            ThreadPool.QueueUserWorkItem(new WaitCallback(this.StatAcceptClient), Administrator.frmAdministratorMain.serverSocket);
        public void StatAcceptClient(object state)
        {
            var serverSocket = (Socket)state;
            this.AppendTextToTextlog("伺服器端開始接受客戶端的連結");

            while (true)
            {
                Socket proxSocket = serverSocket.Accept();

                this.txtLog.Text = string.Format("一個客戶端:{0}連結上\r\n{1}", proxSocket.RemoteEndPoint.ToString(), txtLog.Text);

                clientProxSocketList.Add(proxSocket);

                //伺服器端接受客戶端的訊息

                ThreadPool.QueueUserWorkItem(new WaitCallback(this.RecieveData), proxSocket);
            }
        }
        private void RecieveData(object obj)
        {
            var proxSocket = (Socket)obj;
            byte[] data = new byte[1024 * 1024];
            //方法的返回值代表實際上接受的資料的長度(位元組數)
            while (true)
            {
                int realLen = 0;
                try
                {
                    realLen = proxSocket.Receive(data, 0, data.Length, SocketFlags.None);
                }
                catch (Exception ex)
                {

                    this.txtLog.Text = string.Format("客戶端:{0}非正常退出", proxSocket.RemoteEndPoint.ToString());

                    StopConnetct(proxSocket);
                }

                if (realLen == 0)
                {
                    this.txtLog.Text = string.Format("客戶端:{0}正常退出", proxSocket.RemoteEndPoint.ToString());

                    //對方退出
                    //proxSocket.Shutdown(SocketShutdown.Both);
                    //proxSocket.Close();
                    //clientProxSocketList.Remove(proxSocket);

                    StopConnetct(proxSocket);
                    return;
                }
                string strClientMsg = Encoding.Default.GetString(data, 0, realLen);

                AppendTextToTextlog(string.Format("接受到客戶端:{0}的訊息:{1}\r\n{2}", proxSocket.RemoteEndPoint.ToString(), strClientMsg, txtLog.Text));
            }
        }
    private void StopConnetct(Socket proxSocket)
        {
            try
            {
                if (proxSocket.Connected)
                {
                    proxSocket.Shutdown(SocketShutdown.Both);
                    proxSocket.Close(100);
                }
            }
            catch (Exception ex)
            {

            }
        }

客戶端連線

  //客戶端裂解伺服器端
            //1、建立Socket物件
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            ClientSocket = socket;

            //2、連線伺服器端
            try
            {
                socket.Connect(IPAddress.Parse("192.168.20.240"), int.Parse("50000"));
            }
            catch (Exception ex)
            {
                return;
            }

            //3、傳送訊息,接受訊息
            Thread thread = new Thread(new ParameterizedThreadStart(RecieveData));
            thread.IsBackground = true;
            thread.Start(ClientSocket);
  private void RecieveData(object obj)
        {
            var proxSocket = (Socket)obj;
            byte[] data = new byte[1024 * 1024];
            //方法的返回值代表實際上接受的資料的長度(位元組數)
            while (true)
            {
                int realLen = 0;
                try
                {
                    realLen = proxSocket.Receive(data, 0, data.Length, SocketFlags.None);
                }
                catch (Exception ex)
                {

                    this.txtLog.Text = string.Format("伺服器端:{0}非正常退出", proxSocket.RemoteEndPoint.ToString());
                    StopContnet(); //停止連線
                }

                if (realLen == 0)
                {
                    this.txtLog.Text = string.Format("伺服器端:{0}正常退出", proxSocket.RemoteEndPoint.ToString());

                    StopContnet(); //停止連線
                    return;
                }
            }
        public string ProcessRecieveString(byte[] data,int reallen)
        {
            string str = Encoding.Default.GetString(data, 1, reallen-1);
            return str;
        }
        private void StopContnet()
        {
            try
            {
                if (ClientSocket.Connected)
                {
                    ClientSocket.Shutdown(SocketShutdown.Both);
                    ClientSocket.Close(100);
                }
            }
            catch (Exception ex)
            {

            }
        }

總結

剛開始接觸不太好搞懂,然後出錯也解決不了,這種情況可以去上網百度深入瞭解Socket怎麼實現雙向的通訊連線資料的交換,小生是通過一遍一遍的走程式碼,通過看裡面的引數變化,弄懂了點皮毛!