<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      你也可以寫個服務器 - C# Socket學習2

      續上篇《你也可以寫個聊天程序 - C# Socket學習1》

      前言

      這里說的服務器是Web服務器,是類似IIS、Tomcat之類的,用來響應瀏覽器請求的服務。

      Socket模擬瀏覽器的Url Get請求

      首先瀏覽器的請求是HTTP協議。我們上一篇說過,HTTP是短連接,用完就斷開,是無狀態的。所以我們在等待響應的時候不需要另外開個線程循環等待。
      也就是我們只需要通過Socket和服務器建立連接,然后發送請求,然后接收服務器的響應,這樣就完成了一次請求。
      可是,我們一般訪問網頁的時候都是通過域名,沒有IP也沒有端口,怎么和服務器建立連接了。這里就需要用到我們上篇介紹的幾個類了:

      //根據DNS獲取域名綁定的IP
      foreach (var address in Dns.GetHostEntry("www.baidu.com").AddressList)
      {
          Console.WriteLine($"百度IP:{address}");
      }
      
      //字符串轉IP地址
      IPAddress ipAddress = IPAddress.Parse("192.168.1.101");
      
      //通過IP和端口構造IPEndPoint對象,用于遠程連接
      //通過IP可以確定一臺電腦,通過端口可以確定電腦上的一個程序
      IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 80);
      

      對于HTTP沒有顯示端口默認都是80 (為了簡單這里就先不考慮HTTPS了)
      知道了IP和端口,連接是可以建立了,為了得到正確的響應,我們應該給服務器發送什么消息呢?這里就需要用到HTTP協議了。
      具體協議這里就不說了,我們先F12看看瀏覽器的請求報文,然后依葫蘆畫瓢試試,以http://fanyi-pro.baidu.com為例。(現在找個非HTTPS的地址也是不容易了)

      然后我們代碼實現如下:

      void ...()
      {
          //得到主機信息
          IPHostEntry ipInfo = Dns.GetHostEntry(new Uri("http://fanyi-pro.baidu.com").Host);
          //取得IPAddress[]
          IPAddress[] ipAddr = ipInfo.AddressList;
          //得到服務器ip
          IPAddress ip = ipAddr[0];
          //組合遠程終結點
          IPEndPoint ipEndPoint = new IPEndPoint(ip, 80);
          //創建Socket 實例
          Socket socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
          
          //嘗試連接
          socketClient.Connect(ipEndPoint);
          //發送請求
          Send(socketClient);
          //接收服務器的響應 
          Receive(socketClient); 
      }
      
      //接收來自服務端的消息
      void Receive(Socket socketClient)
      {
          byte[] data = new byte[1024 * 1024];
          while (true)
          {
              //讀取客戶端發送過來的數據
              int readLeng = socketClient.Receive(data, 0, data.Length, SocketFlags.None);
              textBox2.AppendText($"{socketClient.RemoteEndPoint}:{Encoding.UTF8.GetString(data, 0, readLeng)}\r\n");
          }
      }
      
      //發送消息到服務端
      void Send(Socket socketClient)
      {
          //為了方便演示,僅用請求報文的前兩行即可。(切記:需要嚴格按照報文格式。如,最后需要連續兩次換行)
          var msg = $"GET / HTTP/1.1\r\nHost: {new Uri(textBox1.Text).Host}\r\n\r\n";
          socketClient.Send(Encoding.UTF8.GetBytes(msg));
      }
      

      整個流程也就是:

      • 1、dns服務把域名解析成ip
      • 2、通過ip和端口和服務器建立連接(三次握手)
      • 3、獲取html文檔
      • 4、根據文檔里面的鏈接(js、css、img)再重復以上過程

      【注意】:發送報文的時候需要嚴格按照報文格式。如,最后需要連續兩次換行、行末不能有空格等。

      效果圖:

      用Socket實現Web服務器

      Web服務器的實現和我們上一篇的Socket聊天服務端其實也差不多。
      不同之處就在于,解析請求報文,然后按HTTP協議回復標準的響應報文(我這里為了簡單,就沒有按標準的協議來玩,僅僅只是實現了表面的效果)
      代碼如下:

      void ...()
      {
          //1 創建Socket對象
          Socket socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
      
          //2 綁定ip和端口
          IPAddress ip = IPAddress.Parse("127.0.0.1");
          IPEndPoint ipEndPoint = new IPEndPoint(ip, 80);
          socketServer.Bind(ipEndPoint);
      
          //3、開啟偵聽(等待客戶機發出的連接),并設置最大客戶端連接數為10
          socketServer.Listen(10); 
          
          //阻塞等待客戶端連接
          Task.Run(() => { Accept(socketServer); });
      }
      
      //4 阻塞等待客戶端連接
      private static void Accept(Socket socketServer)
      {
          while (true)
          {
              //阻塞等待客戶端連接
              Socket newSocket = socketServer.Accept();
              Task.Run(() => { Receive(newSocket); });
          }
      }
      
      //5 讀取客戶端發送過來的報文
      private static void Receive(Socket newSocket)
      {
          byte[] data = new byte[1024 * 1024];
          while (newSocket.Connected)
          {
              //讀取客戶端發送過來的數據
              int readLeng = newSocket.Receive(data, 0, data.Length, SocketFlags.None);
              //讀取客戶端發來的請求報文
              var requst = Encoding.UTF8.GetString(data, 0, readLeng);
              
              //解析請求報文的請求路徑(可以解析請求路徑、請求文件、文件類型)
              var requstFile = requst.Split("\r\n")[0].Split(" ")[1];
              //回復客戶端響應報文
              Send(newSocket, requstFile);
          }
      }
      
      //6 回復客戶端響應報文
      private static void Send(Socket newSocket, string requstFile)
      {
          //這里如果請求的根目錄,默認顯示Index.html
          if (requstFile == "/" ) requstFile = "/Index.html";
      
          var msg = File.ReadAllText(Directory.GetCurrentDirectory() + requstFile);
          //把消息內容轉成字節數組后發送
          newSocket.Send(Encoding.UTF8.GetBytes(msg));
         
          //回復響應后馬上關閉連接
          newSocket.Shutdown(SocketShutdown.Both);
          newSocket.Close();
      }
      

      效果如下:


      由此我們知道了.net core為什么可以在不需要iis的情況下,一個黑窗體就提供了對網址的訪問。其實也就是KestrelServer通過Socket綁定并監聽端口提供的服務。
      【注意】:我們綁定的ip是127.0.0.1socketServer.Bind(ipEndPoint),所以我們測試的時候只能在瀏覽器輸入127.0.0.1或者localhost。如果想通過內外ip訪問,我們可以綁定任意ipIPAddress.Any。如socketServer.Bind(new IPEndPoint(IPAddress.Any, port))

      為什么不見三次握手

      對于HTTP/TCP可能大家多少都聽過三次握手,可是在我們在用Socket編寫Web服務器的時候并沒有看到相關的東西啊,這是怎么回事。
      因為我們在客戶端執行連接socketClient.Connect(ipEndPoint)的時候已經進行了三次握手

      具體可細讀小坦克大佬的文章。
      也就是說我們在用C#的Socket、TCP、HttpClient的時候根本就不用關注這些細節。
      另外套接字有三種不同的類型:流套接字、數據報套接字和原始套接字。前兩者是標準套接字,分別對應TCP和UDP。而原始套接字則更加底層更加牛逼,普通開發人員一般接觸不到。
      我們說的HTTP、TCP、UDP之類都是網絡協議,那協議到底是什么?通俗的說其實只是你我他之間的一個約定而已,大家都按規定了來那就可以說是協議。
      而HTTP又是建立在TCP之上的,也就是說基礎協議之后再加約定又可以成為一種新的協議。下章我們將用Socket來實現ModbusTCP協議對寄存器讀和寫。

      結束

      posted @ 2019-10-21 08:53  農碼一生  閱讀(3685)  評論(3)    收藏  舉報
      .
      主站蜘蛛池模板: 成人性生交片无码免费看| 国产亚洲精品综合99久久| 91中文字幕在线一区| 亚洲成a人片在线观看中| 国产成人无码A区在线观看视频| 东京热一区二区三区在线| 国产最大成人亚洲精品| 69天堂人成无码免费视频| 日韩精品二区三区四区| 日韩大片高清播放器| 无码天堂亚洲国产av麻豆| 国产精品有码在线观看| 潮喷失禁大喷水无码| 欧美日韩中文字幕视频不卡一二区| 日韩成av在线免费观看| 九九热精品在线观看| 国产成人av一区二区三| 久久精品国产中文字幕| 久热在线中文字幕色999舞| av午夜福利亚洲精品福利| 嗯灬啊灬把腿张开灬动态图| 亚洲国产精品自产在线播放 | 宅男噜噜噜66在线观看| 中文字幕日韩国产精品| 福利一区二区1000| 色色97| 亚洲AVAV天堂AV在线网阿V | 国产在线观看播放av| 在线观看视频一区二区三区| 亚洲AV日韩AV永久无码电影| 辽阳市| 日韩人妻无码一区二区三区| 中文乱码字幕在线中文乱码 | 欧美黑人又粗又大久久久| 亚洲一精品一区二区三区| 国产99在线 | 亚洲| 德令哈市| 欧美国产日韩久久mv| 与子乱对白在线播放单亲国产| 亚洲中文久久久精品无码| 92国产精品午夜福利免费|