小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

c# TCP/IP協(xié)議利用Socket的簡(jiǎn)單通信

 小世界的野孩子 2021-04-23

完全是基礎(chǔ),新手可以隨意看看,大??梢躁P(guān)閉瀏覽頁(yè)了,哈哈。

TCP/IP協(xié)議

TCP/IP是一系列網(wǎng)絡(luò)通信協(xié)議的統(tǒng)稱,其中最核心的兩個(gè)協(xié)議是TCP和IP。TCP稱為傳輸控制協(xié)議,IP稱為互聯(lián)網(wǎng)絡(luò)協(xié)議。

網(wǎng)絡(luò)分層除了OSI模型分層,還有TCP/IP模型分層,將網(wǎng)絡(luò)劃分為四層,應(yīng)用層、傳輸層、網(wǎng)際層、網(wǎng)絡(luò)接口層。TCP/IP模型分層是OSI模型分層的濃縮版

OSI模型和TCP/IP網(wǎng)絡(luò)分層的對(duì)應(yīng)結(jié)構(gòu)及TCP/IP部分協(xié)議族,

 

TCP三次握手

第一次握手:建立連接??蛻舳税l(fā)送連接請(qǐng)求報(bào)文段,將SYN位置為1,Sequence Number為x;然后,客戶端進(jìn)入SYN_SEND狀態(tài),等待服務(wù)器的確認(rèn);
第二次握手:服務(wù)器收到SYN報(bào)文段。服務(wù)器收到客戶端的SYN報(bào)文段,需要對(duì)這個(gè)SYN報(bào)文段進(jìn)行確認(rèn),設(shè)置Acknowledgment Number為x+1(Sequence Number+1);同時(shí),自己自己還要發(fā)送SYN請(qǐng)求信息,將SYN位置為1,Sequence Number為y;服務(wù)器端將上述所有信息放到一個(gè)報(bào)文段(即SYN+ACK報(bào)文段)中,一并發(fā)送給客戶端,此時(shí)服務(wù)器進(jìn)入SYN_RECV狀態(tài);
第三次握手:客戶端收到服務(wù)器的SYN+ACK報(bào)文段。然后將Acknowledgment Number設(shè)置為y+1,向服務(wù)器發(fā)送ACK報(bào)文段,這個(gè)報(bào)文段發(fā)送完畢以后,客戶端和服務(wù)器端都進(jìn)入ESTABLISHED狀態(tài),完成TCP三次握手。

三次握手圖解

在此基礎(chǔ)上,socket連接過(guò)程:

服務(wù)器監(jiān)聽(tīng):服務(wù)器端socket并不定位具體的客戶端socket,而是處于等待監(jiān)聽(tīng)狀態(tài),實(shí)時(shí)監(jiān)控網(wǎng)絡(luò)狀態(tài)。

客戶端請(qǐng)求:客戶端clientSocket發(fā)送連接請(qǐng)求,目標(biāo)是服務(wù)器的serverSocket。為此,clientSocket必須知道serverSocket的地址和端口號(hào),進(jìn)行掃描發(fā)出連接請(qǐng)求。

連接確認(rèn):當(dāng)服務(wù)器socket監(jiān)聽(tīng)到或者是受到客戶端socket的連接請(qǐng)求時(shí),服務(wù)器就響應(yīng)客戶端的請(qǐng)求,建議一個(gè)新的socket,把服務(wù)器socket發(fā)送給客戶端,一旦客戶端確認(rèn)連接,則連接建立。

注:在連接確認(rèn)階段:服務(wù)器socket即使在和一個(gè)客戶端socket建立連接后,還在處于監(jiān)聽(tīng)狀態(tài),仍然可以接收到其他客戶端的連接請(qǐng)求,這也是一對(duì)多產(chǎn)生的原因。

socket連接原理知道了,此處編寫最基本最簡(jiǎn)單的socket通信:

客戶端代碼:

     /// <summary>
        /// 客戶端發(fā)送與服務(wù)端的連接請(qǐng)求,創(chuàng)建與之通信用的Socket
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnLink_Click(object sender, EventArgs e)
        {
            try
            {                   
          //定義一個(gè)用于請(qǐng)求連接服務(wù)器的IP和端口號(hào)
          IPEndPoint ip = new IPEndPoint(IPAddress.Parse(txtIp.Text), Convert.ToInt32(txtPort.Text));//txtIP:IP地址;txtPort:端口號(hào)
          //定義一個(gè)套接字用于請(qǐng)求連接服務(wù)器,包含三個(gè)參數(shù)(IP4尋址協(xié)議,流式連接,Tcp協(xié)議)
          socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

          //請(qǐng)求連接服務(wù)端 
          clientSocket.Connect(ip); 
          //創(chuàng)建一個(gè)通信線程,避免阻塞主線程 
          Thread th = new Thread(CRecive);
          //設(shè)置為后臺(tái)線程,隨著主線程退出而退出
                th.IsBackground = true;
          //啟動(dòng)線程
                th.Start(clientSocket);
          //顯示與服務(wù)端連接情況
                ShowMsg($"{clientSocket.RemoteEndPoint.ToString()}:已連接");
            }
            catch (Exception ex)
            {
          //提示套接字監(jiān)聽(tīng)異常
                ShowMsg($"網(wǎng)絡(luò)錯(cuò)誤");
            }
        }

        /// <summary>
        /// 客戶端不停的接收服務(wù)端發(fā)送過(guò)來(lái)的消息
        /// </summary>
        /// <param name="o"></param>
        void CRecive(object o)
        {
            Socket socketSend = o as Socket;
            while (true)
            {
                try
                {
                    //創(chuàng)建一個(gè)內(nèi)存緩沖區(qū),其大小為1024*1024字節(jié)  即1M
                    byte[] buffer = new byte[1024 * 1024];
                    //將接收到的信息存入到內(nèi)存緩沖區(qū),并返回其字節(jié)數(shù)組的長(zhǎng)度
                    int length = socketSend.Receive(buffer);
                    if (length == 0)
                    {
                        ShowMsg($"{socketSend.RemoteEndPoint.ToString()}:已斷開(kāi)連接");
                        break;
                    }
            //將機(jī)器接受到的字節(jié)數(shù)組轉(zhuǎn)換為人可以讀懂的字符串
                    string str = Encoding.UTF8.GetString(buffer, 0, length);
            //將發(fā)送的字符串信息附加到ShowMsg上
                    ShowMsg($"Ta({socketSend.RemoteEndPoint.ToString()}):{str}");
                }
                catch (Exception ex)
                { }

            }
        }

  

  客戶端向服務(wù)端發(fā)送數(shù)據(jù):

clientSocket.Send(Encoding.UTF8.GetBytes($"{txtWrite.Text}"));

  

服務(wù)端代碼:

      /// <summary>
        /// 開(kāi)啟監(jiān)聽(tīng),等待客戶端連接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnMonitor_Click(object sender, EventArgs e)
        {
            try
            {
                //定義一個(gè)套接字用于監(jiān)聽(tīng)客戶端發(fā)來(lái)的消息,包含三個(gè)參數(shù)(IP4尋址協(xié)議,流式連接,Tcp協(xié)議)
                socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //服務(wù)端發(fā)送信息需要一個(gè)IP地址和端口號(hào)
                IPAddress ip = IPAddress.Parse(txtIp.Text);//IPAddress.Any;
                                                           //將IP地址和端口號(hào)綁定到網(wǎng)絡(luò)節(jié)點(diǎn)point上
                IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text));
                //監(jiān)聽(tīng)綁定的網(wǎng)絡(luò)節(jié)點(diǎn)
                socketWatch.Bind(point);
                ShowMsg("開(kāi)始監(jiān)聽(tīng)。。。");
                //將套接字的監(jiān)聽(tīng)隊(duì)列長(zhǎng)度限制為10           
                socketWatch.Listen(10);
                //負(fù)責(zé)監(jiān)聽(tīng)客戶端的線程:創(chuàng)建一個(gè)監(jiān)聽(tīng)線程
                Thread th = new Thread(SListen);
                //將窗體線程設(shè)置為與后臺(tái)同步,隨著主線程結(jié)束而結(jié)束
                th.IsBackground = true;
                //啟動(dòng)線程
                th.Start(socketWatch);
            }
            catch (Exception ex)
            { }

        }
        /// <summary>
        /// 等待客戶端的連接 并且創(chuàng)建與之通信用的Socket
        /// </summary>
        /// <param name="o"></param>
        void SListen(object o)
        {
            Socket socketWatch = o as Socket;
            while (true)
            {
                try
                {
                    //等待客戶端的連接,并且創(chuàng)建與之通信用的Socket
                    Socket serverSocket = socketWatch.Accept();
                    //獲取客戶端網(wǎng)絡(luò)結(jié)點(diǎn)號(hào)
                    string socketIP = serverSocket.RemoteEndPoint.ToString();
                    ShowMsg($"{socketIP}:已連接");
                    //創(chuàng)建一個(gè)通信線程,避免阻塞主線程
                    Thread th = new Thread(SRecive);
                    th.IsBackground = true;
                    th.Start(serverSocket);
                }
                catch
                { }
            }
        }
        /// <summary>
        /// 服務(wù)端不停的接收客戶端發(fā)送過(guò)來(lái)的消息
        /// </summary>
        /// <param name="o"></param>
        void SRecive(object o)
        {
            Socket socketSend = o as Socket;
            while (true)
            {
                //將接收到的信息存入到內(nèi)存緩沖區(qū),并返回其字節(jié)數(shù)組的長(zhǎng)度
                try
                {
                    //創(chuàng)建一個(gè)內(nèi)存緩沖區(qū),其大小為1024*1024字節(jié)  即1M
                    byte[] buffer = new byte[1024 * 1024];
                    //接收客戶端發(fā)送過(guò)來(lái)的消息
                    int length = socketSend.Receive(buffer);
                    if (length == 0)
                    {
                        ShowMsg($"{socketSend.RemoteEndPoint.ToString()}:已斷開(kāi)連接");
                        break;
                    }
                    //將機(jī)器接受到的字節(jié)數(shù)組轉(zhuǎn)換為人可以讀懂的字符串
                    string str = Encoding.UTF8.GetString(buffer, 0, length);
                    //將發(fā)送的字符串信息附加到ShowMsg上
                    ShowMsg($"Ta({socketSend.RemoteEndPoint.ToString()}):{str}");
                }
                catch (Exception ex) { }
            }
        }

  

  

 服務(wù)端向已連接的客戶端發(fā)送數(shù)據(jù): 

serverSocket.Send(Encoding.UTF8.GetBytes($"{txtWrite.Text}"));

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多