1. 程式人生 > 實用技巧 >Socket建立簡單伺服器和客戶端程式

Socket建立簡單伺服器和客戶端程式

使用Socket程式設計建立簡單伺服器和客戶端

要知道的

Socket—AddressFamily, SocketType, ProtocolType

https://blog.csdn.net/weixin_42464466/article/details/84782870

  • AddressFamily.Internet表示IPV4地址

  • AddressFamily.InternetV6表示IPV6地址

  • SocketType.Stream-資料流 對應TCP協議傳輸資料

  • SocketType.gram-資料報 對應UDP協議傳輸資料

  • ProtocolType.TCP

  • ProtocolType.UDP

EndPoint和IPEndPoint

  • 節點,標明瞭IP地址和埠號,由於 套接字(Socket) 需要繫結在一個程序上面,通過節點(IP: port)來確定

  • 對於TCP/IP協議而言,一臺計算機有 0~66535個埠(有的已被佔用,自定義申請時多使用靠後的埠號)

參考:https://blog.csdn.net/tianlansedeshijie/article/details/95357734

  • IPEndPoint繼承於EndPoint。IPEndPoint引用的時候引數為IP和埠。IPEndPoint iep = new IPEndPoint(IPAddress.Any, 9050);

  • .net中 Bind(EndPoint localEP);方法引數是EndPoint,填入IPEndPoint會按照EndPoint引數執行。

EndPoint是IPEndPoint的基類,IPEndPoint可以強轉為EndPoint。EndPoint ep = (EndPoint)iep;

  • 主要原因是IPEndPoint可以自己寫入IP地址和埠。

Socket三種監聽方式

https://www.cnblogs.com/pctzhang/archive/2012/02/02/2335324.html

  • new Socket(...).Accept()

  • new Socket(...).AcceptAsync(SocketAsyncEventArgs e)

  • new Socket(...).BeginAccept()

Semaphore

#regin和#endregin

歸併摺疊其中的程式碼塊

原始碼

功能

  • 互相傳送一條訊息並接收

  • 暫無使用者自定義訊息內容功能—— Console.ReadLine()

  • 暫無多次通訊功能——執行緒中新增while迴圈或其他(非同步接收方法等)

// 伺服器端
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace Demo01_SocketTest_Sever
{
    class SeverEnd
    {
        private static Socket severSocket;
        static void Main(string[] args)
        {
            // 1. 建立伺服器
            severSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
            // 2. 繫結程序
            severSocket.Bind(new IPEndPoint(IPAddress.Parse("192.168.0.105"),6666));
            // 3. 規定同時連線客戶端數量
            severSocket.Listen(10);
            // 4. 提示伺服器啟動成功
            Console.WriteLine("伺服器啟動成功");
            // 5. 建立Accept等待連線執行緒(Accpet方法如果沒有連線則會掛起,這裡使用執行緒來處理)
            Thread severAcceptThread = new Thread(SeverAccept);// new Thread(委託)
            severAcceptThread.Start();
            // 6. 暫停主執行緒
            Console.ReadKey();
        }

        // 執行緒委託方法——Accept
        private static void SeverAccept()
        {
            // 1. 建立客戶端例項
            Socket clientInstance = severSocket.Accept();
            // 2. 向客戶端傳送訊息肯定連線成功
            clientInstance.Send(Encoding.Default.GetBytes("伺服器發來訊息:連線成功"));
            // 3. 建立Receive接收訊息執行緒(Receive方法如果沒有連線則會掛起,這裡使用執行緒來處理)
            Thread severReceiveThread = new Thread(SeverReceive);
            severReceiveThread.Start(clientInstance);
        }
        // 執行緒委託方法——Receive
        private static void SeverReceive(Object clientSocket)
        {
            // 1. 構建byte陣列(充當緩衝區用於儲存客戶端發來的訊息)
            byte[] data = new byte[1024];
            // 2. 接收客戶端clientSocket發來的訊息,並存儲至data緩衝區,且返回資料位元組長度
            int length = (clientSocket as Socket).Receive(data);
            // 3. 列印輸出接收到的訊息(相當於處理資料)
            Console.WriteLine(Encoding.UTF8.GetString(data,0,length));
        }
    }
}

// 客戶端
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace Demo01_SocketTest_Client
{
    class Program
    {
        private static Socket clientSocket;
        static void Main(string[] args)
        {
            // 1. 建立客戶端Socket
            clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            // 2. 建立連線(請求,對應SeverEnd中第五步)
            clientSocket.Connect(new IPEndPoint(IPAddress.Parse("192.168.0.105"),6666));
            // 3. 提示連線成功
            Console.WriteLine("連線成功");
            // 4. 向伺服器傳送訊息
            clientSocket.Send(Encoding.UTF8.GetBytes("來自客戶端:你好呀伺服器!"));
            // 5. 建立Receive接收訊息執行緒(接收來自伺服器端的訊息),Receive方法如果沒有連線則會掛起,這裡使用執行緒來處理
            Thread clientReceiveThread = new Thread(ClientReceive);
            // 6. 暫停主執行緒
            Console.ReadKey();
        }

        // 執行緒委託方法
        private static void ClientReceive()
        {
            // 1. 構建byte陣列(充當緩衝區用於儲存伺服器端發來的訊息)
            byte[] data = new byte[1024];
            // 2. 接收由伺服器端發來的訊息,並存儲至data緩衝區,且返回訊息位元組長
            int length = clientSocket.Receive(data);
            // 3. 列印輸出接收到的訊息(相當於處理資料)
            Console.WriteLine(Encoding.UTF8.GetString(data,0,length));
        }
    }
}