1. 程式人生 > >C#實戰024:利用Socket進行雙向資訊通訊

C#實戰024:利用Socket進行雙向資訊通訊

      專案開發過程中需要通過伺服器獲取裝置的資訊狀態,這時我們就需要在裝置端開啟監聽來獲取伺服器發來的訊息並執行相應程式來獲取裝置的引數,這個過程我們需要利用Socket進行通訊,這時伺服器是傳送資料,裝置為接受資料,所以這裡我們定義伺服器為客戶端SocketClient,裝置為服務端SocketServer。

Socket用到的幾個方法:

   Socket():建立一個Socket物件

   Bind():繫結一個本地的IP和埠號

   Listen():開啟Socket監聽並指定監聽數量

   Connect():初始化與另一個Socket的連線

   Accept():接收連線並返回一個新的Socket

   Send():傳送資料到Socket

   Receive():從Socket中讀取資料

   Close():關閉Socket,釋放資源

socket 物件引數 (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
第一個引數指socket使用的定址方案,即IPV4或IPV6;
第二個引數指socket的套接字的型別,stream表示流式套接字,dgram表示資料報套接字
第三個引數指socket支援的協議,TCP協議或UDP協議。

客戶端程式碼(已經詳細的解釋了每行程式碼的意思了):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;


namespace SocketClient
{
    class Program
    {
        //建立一個socket的物件
        public static Socket socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        private static byte[] result = new byte[1024];//定義一個位元組陣列,相當於快取
        public static string serverIp = "127.0.0.1";//設定伺服器IP地址
        public static int serverPort = 8888;//設定伺服器埠
        static void Main(string[] args)
        {
            SocketClient();//呼叫SocketClient方法
        }
        /// <summary>
        /// 建立Socket客戶端
        /// </summary>
        public static void SocketClient()
        {
            IPAddress ip = IPAddress.Parse(serverIp);//伺服器IP地址
            IPEndPoint point = new IPEndPoint(ip, serverPort);//伺服器IP地址及埠
            try
            {
                socketClient.Connect(point);//連結伺服器IP與埠
                Console.WriteLine("連線伺服器成功");
            }
            catch (Exception)
            {
                Console.WriteLine("連線伺服器失敗,請按回車鍵退出!");
                return;
            }
            //通過socketClient接受伺服器的資料
            int num = socketClient.Receive(result);//把接受到的資料存到bytes陣列中並賦值給num
            Console.WriteLine("接收伺服器訊息:{0}", Encoding.UTF8.GetString(result, 0, num));  //GetString(result, 0, num)把從0到num的位元組變成String
            try
            {
                Thread.Sleep(1000);    //等待1秒鐘  
                //通過 socketClient 向伺服器傳送資料
                string sendMessage = "已成功接到SocketClient傳送的訊息";//傳送到服務端的內容
                byte[] send = Encoding.UTF8.GetBytes(sendMessage);//Encoding.UTF8.GetBytes()將字串轉換成位元組(避免亂碼)
                socketClient.Send(send);  //將接受成功的訊息返回給SocketServer伺服器 
                Console.WriteLine("傳送完畢:{0}",sendMessage);
                
            }
            catch
            {
                socketClient.Shutdown(SocketShutdown.Both);//禁止Socket上的傳送和接受
                socketClient.Close();//關閉Socket並釋放資源
            }
            Console.ReadLine();
            socketClient.Close();//關閉Socket並釋放資源
        }
    }
}

伺服器端程式碼(已經詳細的解釋了每行程式碼的意思了): 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace SocketServer
{
    class Program
    {
        static void Main(string[] args)
        {
            SocketServer();
        }
        //建立一個socket的物件
        public static Socket socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        public static string serverIp = "127.0.0.1";//設定IP
        public static int serverPort = 8888;//設定埠
        public static byte[] result = new byte[1024];//定義一個位元組陣列,相當於快取
        /// <summary>
        /// 建立socket服務
        /// </summary>
        public static void SocketServer()
        {
            IPAddress ip = IPAddress.Parse(serverIp);//伺服器IP地址
            IPEndPoint point = new IPEndPoint(ip, serverPort);//獲取埠
            socketServer.Bind(point);//繫結IP地址及埠
            socketServer.Listen(100);//開啟監聽並設定最多10個排隊連線請求 
            Console.WriteLine("啟動監聽{0}成功", socketServer.LocalEndPoint.ToString());//輸出啟動成功提示

            Thread thread = new Thread(ListenSocket);//建立一個監聽程序
            thread.Start();//執行
            Console.ReadLine();
        }
        /// <summary>
        /// 監聽客戶端連線
        /// </summary>
        public static void ListenSocket()
        {
            while (true)
            {
                Socket clientSocket = socketServer.Accept();//接收連線並返回一個新的Socket
                clientSocket.Send(Encoding.UTF8.GetBytes("伺服器連線成功"));//在客戶端顯示"伺服器連線成功"提示
                Thread recevieThread = new Thread(ReceiveMessage);//建立一個接受資訊的程序
                recevieThread.Start(clientSocket);//執行新的Socket接受資訊
            }
        }
        /// <summary>
        ///  接受Socket訊息
        /// </summary>
        /// <param name="clientSocket"></param>
        public static void ReceiveMessage(object clientSocket)
        {
            Socket SocketClient = (Socket)clientSocket;
            while (true)
            {
                try
                {
                    //通過clientsocket接收資料
                    int num = SocketClient.Receive(result);//把接受到的資料存到bytes陣列中並賦值給num
                    Console.WriteLine("接收客戶端{0} 的訊息:{1}", SocketClient.RemoteEndPoint.ToString(), Encoding.UTF8.GetString(result, 0, num));//GetString(result, 0, num)把從0到num的位元組變成String
                    Thread.Sleep(1000);    //等待1秒鐘  
                    //給SocketClient客戶端返回資訊
                    string sendMessage = "已成功接到socketServer傳送的訊息";//傳送到客戶端的內容
                    byte[] send = Encoding.UTF8.GetBytes(sendMessage);//Encoding.UTF8.GetBytes()將字串轉換成位元組(避免亂碼)
                    SocketClient.Send(send);//將接受成功的訊息返回給SocketClient客戶端
                    SocketClient.Close();//關閉Socket並釋放資源
                }
                catch { }
            }
        }
    }
}