Socket服務器端

根據以上總結的客戶端與服務器端的通信過程,

我們先來寫一個服務器端


private void btnOpen_Click(object sender, EventArgs e)
        {
            //創建一個Socket對象
            Socket severSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //綁定端口和IP
            IPEndPoint endPoint=new IPEndPoint(IPAddress.Parse(txtIP.Text),int.Parse(txtPort.Text));
            severSocket.Bind(endPoint);
            //開始監聽            
            severSocket.Listen(10);
            //開始連接          
            //主線程會在這裏一直阻塞,直到連接到一個客戶端
            //返回值是一個代理通信Socket對象
            Socket socket = severSocket.Accept();
            txtLog.Text = "已成功連接:"+socket.RemoteEndPoint+"\r\n" + this.txtLog.Text;
            //發送消息
            byte[] myBuffer=Encoding.Default.GetBytes(DateTime.Now.ToString());
            socket.Send(myBuffer);
            txtLog.Text = "消息已成功發送\r\n" + this.txtLog.Text;

            //關閉代理Socket
            socket.Shutdown(SocketShutdown.Both);
            socket.Close();

            //關閉總的Socket
            txtLog.Text = "連接已斷開\r\n" + this.txtLog.Text;
            severSocket.Close();
           
        }
這裏只要根據圖上的步驟一步一步來基本沒什麼大問題。

只需要注意兩點

(1)Socket對象的Accept方法會阻塞線程,如果在主線程執行會出現卡死的現象,直到你連接到客戶端。

(2)關於txtLog.Text的寫法,可能有人會有疑問,其實是很簡單的一個道理,

將最新的消息顯示在頭上,如果顯示數據很多的話,優勢就很明顯了,不必總是往下滾滾動條


顯示效果如下:


這裏可以使用多線程方法來解決剛纔卡死的問題

創建一個新的線程來執行阻塞等待Accept方法

代碼如下:

  private void btnOpen_Click(object sender, EventArgs e)
        {
            //創建一個Socket對象
            Socket severSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //綁定端口和IP
            IPEndPoint endPoint=new IPEndPoint(IPAddress.Parse(txtIP.Text),int.Parse(txtPort.Text));
            severSocket.Bind(endPoint);
            //開始監聽            
            severSocket.Listen(10);

            //用別的線程來連接客戶端
            ThreadPool.QueueUserWorkItem(new WaitCallback(CallBackSocket),severSocket);

            
        }

        public  void CallBackSocket(object obj) 
        {
            //將參數obj強轉成Socket類型
            Socket severSocket = (Socket)obj;
            //開始連接          
            //主線程會在這裏一直阻塞,直到連接到一個客戶端
            //返回值是一個代理通信Socket對象

            //可能連接多個客戶端,需要循環
            while (true)
            {
                Socket socket = severSocket.Accept();
                txtLog.Text = "已成功連接:" + socket.RemoteEndPoint + "\r\n" + this.txtLog.Text;
                //發送消息
                byte[] myBuffer = Encoding.Default.GetBytes(DateTime.Now.ToString());
                socket.Send(myBuffer);
                txtLog.Text = "消息已成功發送\r\n" + this.txtLog.Text;

                //關閉代理Socket
                socket.Shutdown(SocketShutdown.Both);
                socket.Close();

                //關閉總的Socket
                txtLog.Text = "連接已斷開\r\n" + this.txtLog.Text;
                //severSocket.Close(); 
            }
        }

如果出現跨線程訪問控件的錯誤,請查看之前的多線程學習博客裏的解決方案


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章