91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用C#中的Socket發送HTTP/HTTPS請求

發布時間:2020-07-11 10:51:20 來源:億速云 閱讀:268 作者:Leah 欄目:編程語言

如何使用C#中的Socket發送HTTP/HTTPS請求?針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

C# 自帶的HttpWebRequest效率太低,對于自組HTTP封包不好操作。

在寫超級SQL注入工具時,研究了很長一段時間如何使用Socket來發送HTTP、HTTPS請求。

經過一年的修改和測試,可完美、高效發送并解析HTTP/HTTPS請求。修改過無數次bug。

在這里把核心代碼分享出來,供大家學習或做開發參考。

用這個代碼寫了一個簡單的HTTP發包工具。供大家參考。

如何使用C#中的Socket發送HTTP/HTTPS請求

工具下載:

HTTPTool.rar

核心類:HTTP.cs

using System;
using System.Collections.Generic;
using System.Text;
using tools;
using System.Net;
using System.Net.Sockets;
using System.IO.Compression;
using System.IO;
using System.Net.Security;
using System.Text.RegularExpressions;
using System.Threading;
using System.Diagnostics;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using HTTPTool;
 
namespace tools
{
  public class HTTP
  {
    public const char T = '
';
    public const String CT = "
";
    public const String CTRL = "
 
";
    public const String Content_Length_Str = "content-length: ";
    public const String Content_Length_Str_M = "Content-Length: ";
    public const String Content_Length = "content-length";
    public const String Content_Encoding = "content-encoding";
    public const String Transfer_Encoding = "transfer-encoding";
    public const String Connection = "connection";
    public static Main main = null;
    public static long index = 0;
    public void initMain(Main m)
    {
      main = m;
    }
 
    /**
     * 
     發生異常嘗試重連 
     *
     */
    public static ServerInfo sendRequestRetry(Boolean isSSL, int tryCount, String host, int port, String payload, String request, int timeout, String encoding, Boolean foward_302)
    {
      int count = 0;
      Interlocked.Increment(ref index);
      ServerInfo server = new ServerInfo();
      timeout = timeout * 1000;
      while (true)
      {
        if (count >= tryCount) break;
 
        try
        {
          if (!isSSL)
          {
            server = sendHTTPRequest(count, host, port, payload, request, timeout, encoding, foward_302);
            return server;
          }
          else
          {
 
            server = sendHTTPSRequest(count, host, port, payload, request, timeout, encoding, foward_302);
            return server;
 
          }
        }
        catch (Exception e)
        {
          Tools.SysLog("發包發生異常,正在重試----" + e.Message);
          server.timeout = true;
          continue;
        }
        finally
        {
          count++;
        }
 
      }
      return server;
 
    }
 
    private static void checkContentLength(ref ServerInfo server, ref String request)
    {
 
      //重新計算并設置Content-length
      int sindex = request.IndexOf(CTRL);
      server.reuqestHeader = request;
      if (sindex != -1)
      {
        server.reuqestHeader = request.Substring(0, sindex);
        server.reuqestBody = request.Substring(sindex + 4, request.Length - sindex - 4);
        int contentLength = Encoding.UTF8.GetBytes(server.reuqestBody).Length;
        String newContentLength = Content_Length_Str_M + contentLength;
 
        if (request.IndexOf(Content_Length_Str_M) != -1)
        {
          request = Regex.Replace(request, Content_Length_Str_M + "d+", newContentLength);
        }
        else
        {
          request = request.Insert(sindex, "
" + newContentLength);
        }
      }
      else
      {
        request = Regex.Replace(request, Content_Length_Str + "d+", Content_Length_Str_M + "0");
        request += CTRL;
      }
 
 
    }
 
    private static void doHeader(ref ServerInfo server, ref String[] headers)
    {
 
      for (int i = 0; i < headers.Length; i++)
      {
        if (i == 0)
        {
 
          server.code = Tools.convertToInt(headers[i].Split(' ')[1]);
 
        }
        else
        {
          String[] kv = Regex.Split(headers[i], ": ");
          String key = kv[0].ToLower();
          if (!server.headers.ContainsKey(key))
          {
            //自動識別編碼
            if ("content-type".Equals(key))
            {
              String hecnode = getHTMLEncoding(kv[1], "");
              if (!String.IsNullOrEmpty(hecnode))
              {
                server.encoding = hecnode;
              }
            }
            if (kv.Length > 1)
            {
              server.headers.Add(key, kv[1]);
            }
            else
            {
              server.headers.Add(key, "");
            }
          }
        }
      }
 
    }
 
 
    private static ServerInfo sendHTTPRequest(int count, String host, int port, String payload, String request, int timeout, String encoding, Boolean foward_302)
    {
 
      String index = Thread.CurrentThread.Name + HTTP.index;
      Stopwatch sw = new Stopwatch();
      sw.Start();
      ServerInfo server = new ServerInfo();
      TcpClient clientSocket = null;
      int sum = 0;
      try
      {
        if (port > 0 && port <= 65556)
        {
          //編碼處理
          server.request = request;
          TimeOutSocket tos = new TimeOutSocket();
          clientSocket = tos.Connect(host, port, timeout);
          if (sw.ElapsedMilliseconds >= timeout)
          {
            return server;
          }
          clientSocket.SendTimeout = timeout - tos.useTime;
          if (clientSocket.Connected)
          {
            checkContentLength(ref server, ref request);
            server.request = request;
 
            byte[] requestByte = Encoding.UTF8.GetBytes(request);
            clientSocket.Client.Send(requestByte);
            byte[] responseBody = new byte[1024 * 1000];
            int len = 0;
            //獲取header頭
            String tmp = "";
            StringBuilder sb = new StringBuilder();
            clientSocket.ReceiveTimeout = timeout - (int)sw.ElapsedMilliseconds;
            do
            {
              byte[] responseHeader = new byte[1];
              len = clientSocket.Client.Receive(responseHeader, 1, SocketFlags.None);
              if (len == 1)
              {
 
                char c = (char)responseHeader[0];
                sb.Append(c);
                if (c.Equals(T))
                {
                  tmp = String.Concat(sb[sb.Length - 4], sb[sb.Length - 3], sb[sb.Length - 2], c);
                }
              }
            } while (!tmp.Equals(CTRL) && sw.ElapsedMilliseconds < timeout);
 
            server.header = sb.ToString().Replace(CTRL, "");
            String[] headers = Regex.Split(server.header, CT);
            if (headers != null && headers.Length > 0)
            {
              //處理header
              doHeader(ref server, ref headers);
              //自動修正編碼
              if (!String.IsNullOrEmpty(server.encoding))
              {
                encoding = server.encoding;
              }
              Encoding encod = Encoding.GetEncoding(encoding);
 
              //302 301跳轉
              if ((server.code == 302 || server.code == 301) && foward_302)
              {
                StringBuilder rsb = new StringBuilder(server.request);
                int urlStart = server.request.IndexOf(" ") + 1;
                int urlEnd = server.request.IndexOf(" HTTP");
                if (urlStart != -1 && urlEnd != -1)
                {
                  String url = server.request.Substring(urlStart, urlEnd - urlStart);
                  rsb.Remove(urlStart, url.Length);
                  String location = server.headers["location"];
                  if (!server.headers["location"].StartsWith("/") && !server.headers["location"].StartsWith("http"))
                  {
                    location = Tools.getCurrentPath(url) + location;
                  }
                  rsb.Insert(urlStart, location);
 
                  return sendHTTPRequest(count, host, port, payload, rsb.ToString(), timeout, encoding, false);
                }
 
              }
 
 
              //根據請求頭解析
              if (server.headers.ContainsKey(Content_Length))
              {
                int length = int.Parse(server.headers[Content_Length]);
 
                while (sum < length && sw.ElapsedMilliseconds < timeout)
                {
                  int readsize = length - sum;
                  len = clientSocket.Client.Receive(responseBody, sum, readsize, SocketFlags.None);
                  if (len > 0)
                  {
                    sum += len;
                  }
                }
              }
              //解析chunked傳輸
              else if (server.headers.ContainsKey(Transfer_Encoding))
              {
                //讀取長度
                int chunkedSize = 0;
                byte[] chunkedByte = new byte[1];
                //讀取總長度
                sum = 0;
                do
                {
                  String ctmp = "";
                  do
                  {
                    len = clientSocket.Client.Receive(chunkedByte, 1, SocketFlags.None);
                    ctmp += Encoding.UTF8.GetString(chunkedByte);
 
                  } while ((ctmp.IndexOf(CT) == -1) && (sw.ElapsedMilliseconds < timeout));
 
                  chunkedSize = Tools.convertToIntBy16(ctmp.Replace(CT, ""));
 
                  //chunked的結束0
 
是結束標志,單個chunked塊
結束
                  if (ctmp.Equals(CT))
                  {
                    continue;
                  }
                  if (chunkedSize == 0)
                  {
                    //結束了
                    break;
                  }
                  int onechunkLen = 0;
                  while (onechunkLen < chunkedSize && sw.ElapsedMilliseconds < timeout)
                  {
                    len = clientSocket.Client.Receive(responseBody, sum, chunkedSize - onechunkLen, SocketFlags.None);
                    if (len > 0)
                    {
                      onechunkLen += len;
                      sum += len;
                    }
                  }
 
                  //判斷
                } while (sw.ElapsedMilliseconds < timeout);
              }
              //connection close方式或未知body長度
              else
              {
                while (sw.ElapsedMilliseconds < timeout)
                {
                  if (clientSocket.Client.Poll(timeout, SelectMode.SelectRead))
                  {
                    if (clientSocket.Available > 0)
                    {
                      len = clientSocket.Client.Receive(responseBody, sum, (1024 * 200) - sum, SocketFlags.None);
                      if (len > 0)
                      {
                        sum += len;
                      }
                    }
                    else
                    {
                      break;
                    }
                  }
                }
              }
              //判斷是否gzip
              if (server.headers.ContainsKey(Content_Encoding))
              {
                server.body = unGzip(responseBody, sum, encod);
              }
              else
              {
                server.body = encod.GetString(responseBody, 0, sum);
              }
 
 
            }
          }
 
        }
      }
      catch (Exception e)
      {
        Exception ee = new Exception("HTTP發包錯誤!錯誤消息:" + e.Message + e.TargetSite.Name + "----發包編號:" + index);
        throw ee;
      }
      finally
      {
        sw.Stop();
        server.length = sum;
        server.runTime = (int)sw.ElapsedMilliseconds;
        if (clientSocket != null)
        {
          clientSocket.Close();
        }
      }
      return server;
 
    }
 
    private static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
      return true;
    }
    private static ServerInfo sendHTTPSRequest(int count, String host, int port, String payload, String request, int timeout, String encoding, Boolean foward_302)
    {
      String index = Thread.CurrentThread.Name + HTTP.index;
      Stopwatch sw = new Stopwatch();
      sw.Start();
      ServerInfo server = new ServerInfo();
 
      int sum = 0;
 
      TcpClient clientSocket = null; ;
 
      try
      {
 
        if (port > 0 && port <= 65556)
        {
 
          TimeOutSocket tos = new TimeOutSocket();
          clientSocket = tos.Connect(host, port, timeout);
          if (sw.ElapsedMilliseconds >= timeout)
          {
            return server;
          }
          clientSocket.SendTimeout = timeout - tos.useTime;
 
          SslStream ssl = null;
          if (clientSocket.Connected)
          {
            ssl = new SslStream(clientSocket.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate));
            SslProtocols protocol = SslProtocols.Ssl3 | SslProtocols.Ssl2 | SslProtocols.Tls;
            ssl.AuthenticateAsClient(host, null, protocol, false);
            if (ssl.IsAuthenticated)
            {
              checkContentLength(ref server, ref request);
              server.request = request;
              byte[] requestByte = Encoding.UTF8.GetBytes(request);
              ssl.Write(requestByte);
              ssl.Flush();
            }
          }
          server.request = request;
          byte[] responseBody = new byte[1024 * 1000];
          int len = 0;
          //獲取header頭
          String tmp = "";
 
          StringBuilder sb = new StringBuilder();
          StringBuilder bulider = new StringBuilder();
          clientSocket.ReceiveTimeout = timeout - (int)sw.ElapsedMilliseconds;
          do
          {
            byte[] responseHeader = new byte[1];
            int read = ssl.ReadByte();
 
            char c = (char)read;
            sb.Append(c);
            if (c.Equals(T))
            {
              tmp = String.Concat(sb[sb.Length - 4], sb[sb.Length - 3], sb[sb.Length - 2], c);
            }
 
          } while (!tmp.Equals(CTRL) && sw.ElapsedMilliseconds < timeout);
 
          server.header = sb.ToString().Replace(CTRL, "");
          String[] headers = Regex.Split(server.header, CT);
          //處理header
          doHeader(ref server, ref headers);
          //自動修正編碼
          if (!String.IsNullOrEmpty(server.encoding))
          {
            encoding = server.encoding;
          }
          Encoding encod = Encoding.GetEncoding(encoding);
          //302 301跳轉
          if ((server.code == 302 || server.code == 301) && foward_302)
          {
 
            int urlStart = server.request.IndexOf(" ");
            int urlEnd = server.request.IndexOf(" HTTP");
            if (urlStart != -1 && urlEnd != -1)
            {
              String url = server.request.Substring(urlStart + 1, urlEnd - urlStart - 1);
              if (!server.headers["location"].StartsWith("/") && !server.headers["location"].StartsWith("https"))
              {
                server.request = server.request.Replace(url, Tools.getCurrentPath(url) + server.headers["location"]);
              }
              else
              {
                server.request = server.request.Replace(url, server.headers["location"]);
              }
 
              return sendHTTPSRequest(count, host, port, payload, server.request, timeout, encoding, false);
            }
 
          }
 
 
          //根據請求頭解析
          if (server.headers.ContainsKey(Content_Length))
          {
            int length = int.Parse(server.headers[Content_Length]);
            while (sum < length && sw.ElapsedMilliseconds < timeout)
            {
              len = ssl.Read(responseBody, sum, length - sum);
              if (len > 0)
              {
                sum += len;
              }
            }
          }
          //解析chunked傳輸
          else if (server.headers.ContainsKey(Transfer_Encoding))
          {
            //讀取長度
            int chunkedSize = 0;
            byte[] chunkedByte = new byte[1];
            //讀取總長度
            sum = 0;
            do
            {
              String ctmp = "";
              do
              {
                len = ssl.Read(chunkedByte, 0, 1);
                ctmp += Encoding.UTF8.GetString(chunkedByte);
 
              } while (ctmp.IndexOf(CT) == -1 && sw.ElapsedMilliseconds < timeout);
 
              chunkedSize = Tools.convertToIntBy16(ctmp.Replace(CT, ""));
 
              //chunked的結束0
 
是結束標志,單個chunked塊
結束
              if (ctmp.Equals(CT))
              {
                continue;
              }
              if (chunkedSize == 0)
              {
                //結束了
                break;
              }
              int onechunkLen = 0;
 
              while (onechunkLen < chunkedSize && sw.ElapsedMilliseconds < timeout)
              {
                len = ssl.Read(responseBody, sum, chunkedSize - onechunkLen);
                if (len > 0)
                {
                  onechunkLen += len;
                  sum += len;
                }
              }
 
              //判斷
            } while (sw.ElapsedMilliseconds < timeout);
          }
          //connection close方式或未知body長度
          else
          {
            while (sw.ElapsedMilliseconds < timeout)
            {
              if (clientSocket.Client.Poll(timeout, SelectMode.SelectRead))
              {
                if (clientSocket.Available > 0)
                {
                  len = ssl.Read(responseBody, sum, (1024 * 200) - sum);
                  if (len > 0)
                  {
                    sum += len;
                  }
                }
                else
                {
                  break;
                }
              }
            }
          }
          //判斷是否gzip
          if (server.headers.ContainsKey(Content_Encoding))
          {
            server.body = unGzip(responseBody, sum, encod);
          }
          else
          {
            server.body = encod.GetString(responseBody, 0, sum);
          }
        }
 
      }
      catch (Exception e)
      {
        Exception ee = new Exception("HTTPS發包錯誤!錯誤消息:" + e.Message + "----發包編號:" + index);
        throw ee;
      }
      finally
      {
        sw.Stop();
        server.length = sum;
        server.runTime = (int)sw.ElapsedMilliseconds;
 
        if (clientSocket != null)
        {
          clientSocket.Close();
        }
      }
      return server;
 
    }
 
    public static String unGzip(byte[] data, int len, Encoding encoding)
    {
 
      String str = "";
      MemoryStream ms = new MemoryStream(data, 0, len);
      GZipStream gs = new GZipStream(ms, CompressionMode.Decompress);
      MemoryStream outbuf = new MemoryStream();
      byte[] block = new byte[1024];
 
      try
      {
 
        while (true)
        {
          int bytesRead = gs.Read(block, 0, block.Length);
          if (bytesRead <= 0)
          {
            break;
          }
          else
          {
            outbuf.Write(block, 0, bytesRead);
          }
        }
        str = encoding.GetString(outbuf.ToArray());
      }
      catch (Exception e)
      {
        Tools.SysLog("解壓Gzip發生異常----" + e.Message);
      }
      finally
      {
        outbuf.Close();
        gs.Close();
        ms.Close();
 
      }
      return str;
 
    }
    public static String getHTMLEncoding(String header, String body)
    {
      if (String.IsNullOrEmpty(header) && String.IsNullOrEmpty(body))
      {
        return "";
      }
      body = body.ToUpper();
      Match m = Regex.Match(header, @"charsets*=s*""?(?<charset>[^""]*)", RegexOptions.IgnoreCase);
      if (m.Success)
      {
        return m.Groups["charset"].Value.ToUpper();
      }
      else
      {
        if (String.IsNullOrEmpty(body))
        {
          return "";
        }
        m = Regex.Match(body, @"charsets*=s*""?(?<charset>[^""]*)", RegexOptions.IgnoreCase);
        if (m.Success)
        {
          return m.Groups["charset"].Value.ToUpper();
        }
      }
      return "";
    }
  }
}

關于如何使用C#中的Socket發送HTTP/HTTPS請求問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

金湖县| 搜索| 南皮县| 儋州市| 富顺县| 双流县| 湘潭市| 三门峡市| 临沂市| 罗源县| 桂阳县| 上犹县| 徐闻县| 天津市| 山东省| 武清区| 荆门市| 论坛| 诸暨市| 观塘区| 莱阳市| 宜宾县| 如皋市| 宜丰县| 耒阳市| 田东县| 志丹县| 疏附县| 奎屯市| 延安市| 禄丰县| 贡觉县| 资阳市| 利川市| 合肥市| 神池县| 广河县| 佛坪县| 获嘉县| 东乌珠穆沁旗| 呼和浩特市|