C#에서 소켓을 사용하여 HTTP/HTTPS 요청 예제를 보내는 방법에 대한 자세한 설명
이 기사에서는 주로 소켓을 사용하여 HTTP/HTTPS 요청을 보내는 C#의 구현 코드를 소개합니다. 필요한 친구는 이를 참조할 수 있습니다.
C#에 내장된 HttpWebRequest는 자체 구성 HTTP 패킷에 비해 너무 비효율적이고 작동하기 어렵습니다.
슈퍼 SQL 인젝션 툴을 작성하면서 소켓을 이용해 HTTP, HTTPS 요청을 보내는 방법을 오랫동안 연구했습니다.
1년간의 수정과 테스트 끝에 HTTP/HTTPS 요청을 완벽하고 효율적으로 보내고 구문 분석할 수 있습니다. 수많은 버그를 수정했습니다.
모든 사람이 개발 참조를 배우고 수행할 수 있도록 핵심 코드가 여기에 공유됩니다.
저는 이 코드를 사용하여 간단한 HTTP 패킷 전송 도구를 작성했습니다. 당신의 참고를 위해.
도구 다운로드:
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#에서 소켓을 사용하여 HTTP/HTTPS 요청 예제를 보내는 방법에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











이 기사에서는 주로 IO 멀티플렉싱을 소개하는 php+socket과 php+socket이 웹 서버를 구현하는 방법에 대한 관련 지식을 제공합니다. 관심 있는 친구들은 아래를 살펴보시면 모두에게 도움이 되길 바랍니다.

1. TCP 프로토콜 기반 소켓 프로그래밍 1. 소켓 워크플로는 서버 측에서 시작됩니다. 서버는 먼저 소켓을 초기화한 다음 포트에 바인드하고 포트를 수신하며 차단을 위해 승인을 호출하고 클라이언트가 연결될 때까지 기다립니다. 이때 클라이언트가 Socket을 초기화한 후 서버에 연결(connect)하면, 연결에 성공하면 클라이언트와 서버 간의 연결이 성립된다. 클라이언트는 데이터 요청을 보내고, 서버는 요청을 받아 요청을 처리한 후 클라이언트에 응답 데이터를 보내고, 클라이언트는 데이터를 읽고 마지막으로 연결을 종료합니다. 이를 구현하려면 다음 Python 코드를 사용하세요. : importso

SpringBoot 측의 첫 번째 단계는 종속성을 도입하는 것입니다. 먼저 WebSocket에 필요한 종속성과 com.alibabafastjson1.2.73org.springframework.bootspring-boot-starter-websocket 출력 형식을 처리하기 위한 종속성을 도입해야 합니다. 두 번째 단계는 WebSocket 구성 클래스 importorg를 생성하는 것입니다. springframework.context.annotation.Bean;importorg.springframework.context.annotation.Config

C#의 일반적인 네트워크 통신 및 보안 문제와 해결 방법 오늘날 인터넷 시대에 네트워크 통신은 소프트웨어 개발에 없어서는 안 될 부분이 되었습니다. C#에서는 일반적으로 데이터 전송 보안, 네트워크 연결 안정성 등과 같은 일부 네트워크 통신 문제가 발생합니다. 이 문서에서는 C#의 일반적인 네트워크 통신 및 보안 문제에 대해 자세히 설명하고 해당 솔루션과 코드 예제를 제공합니다. 1. 네트워크 통신 문제 네트워크 연결 중단: 네트워크 통신 과정에서 네트워크 연결이 중단될 수 있으며, 이로 인해

오늘날 인공지능(AI) 기술 개발은 본격화되고 있으며, 다양한 분야에서 큰 잠재력과 영향력을 보여주고 있습니다. 오늘 Dayao는 여러분에게 몇 가지 참고 자료를 제공하고자 4개의 .NET 오픈 소스 AI 모델 LLM 관련 프로젝트 프레임워크를 공유할 것입니다. https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.mdSemanticKernelSemanticKernel은 OpenAI, Azure와 같은 대규모 언어 모델(LLM)을 통합하도록 설계된 오픈 소스 소프트웨어 개발 키트(SDK)입니다.

PHP 소켓을 연결할 수 없는 문제에 대한 해결책: 1. PHP에서 소켓 확장이 활성화되어 있는지 확인하십시오. 2. php.ini 파일을 열고 "php_sockets.dll"이 로드되었는지 확인하십시오. 3. "php_sockets.dll"의 주석을 제거하십시오. ".

PHP는 다양한 웹 애플리케이션을 개발하는 데 사용할 수 있는 일반적으로 사용되는 개발 언어입니다. 일반적인 HTTP 요청 및 응답 외에도 PHP는 소켓을 통한 네트워크 통신을 지원하여 보다 유연하고 효율적인 데이터 상호 작용을 달성합니다. 이 기사에서는 PHP에서 소켓 통신을 구현하는 방법과 기술을 소개하고 특정 코드 예제를 첨부합니다. 소켓 통신이란 무엇입니까? 소켓은 서로 다른 컴퓨터 간에 데이터를 전송할 수 있는 네트워크 통신 방법입니다. 작성자: S
