c# – 检查请求是否来自套接字侦听器中的HTTP或HTTPS

c# – 检查请求是否来自套接字侦听器中的HTTP或HTTPS,第1张

概述我有多线程异步套接字监听器.我想检查请求是否安全.但我想在AcceptCallBack方法中检查不是ReceiveCallBack. 我会这样做,因为我希望我的代码适用于HTTP和HTTPS.如果请求来自HTTPS,我将继续使用经过身份验证的SslStream而不是原始套接字. 这是我的代码: using System;using System.Net;using System.Net.Soc 我有多线程异步套接字监听器.我想检查请求是否安全.但我想在AcceptCallBack方法中检查不是ReceiveCallBack.

我会这样做,因为我希望我的代码适用于http和httpS.如果请求来自httpS,我将继续使用经过身份验证的SslStream而不是原始套接字.

这是我的代码:

using System;using System.Net;using System.Net.sockets;using System.Threading;using System.Text;namespace LearnRequestType{    class StackOverFlow    {        private static Readonly ManualresetEvent _manualresetEvent = new ManualresetEvent(false);        private voID StartListening()        {            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any,9002);            if (localEndPoint != null)            {                Socket Listener = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);                if (Listener != null)                {                    Listener.Bind(localEndPoint);                    Listener.Listen(10);                    Console.Writeline("Socket Listener is running...");                    Listener.BeginAccept(new AsyncCallback(AcceptCallback),Listener);                }            }        }        private voID AcceptCallback(IAsyncResult ar)        {            _manualresetEvent.Set();            Socket Listener = (Socket)ar.AsyncState;            Socket handler = Listener.EndAccept(ar);            StateObject state = new StateObject();            state.workSocket = handler;            // I want to understand if request comes from http or httpS before this line.            handler.BeginReceive(state.buffer,StateObject.BufferSize,new AsyncCallback(ReceiveCallback),state);            Listener.BeginAccept(new AsyncCallback(AcceptCallback),Listener);        }        private voID ReceiveCallback(IAsyncResult result)        {            StateObject state = (StateObject)result.AsyncState;            Socket handler = state.workSocket;            string clIEntIP = ((IPEndPoint)handler.RemoteEndPoint).Address.ToString();            int numBytesReceived = handler.EndReceive(result);            if (!handler.Connected)            {                handler.Close();                return;            }            // Read incoming data...            if (numBytesReceived > 0)            {                state.sb.Append(EnCoding.ASCII.GetString(state.buffer,numBytesReceived));                // Read incoming data line by line.                string[] lines = state.sb.ToString().Split('\n');                if (lines[lines.Length - 1] == "<EOF>")                {                    // We received all data. Do something...                }                else                {                    // We dIDn't receive all data. Continue reading...                    handler.BeginReceive(state.buffer,state.buffer.Length,SocketFlags.None,state);                }            }        }    }}public class StateObject{    public Socket workSocket = null;    public const int BufferSize = 256;    public byte[] buffer = new byte[BufferSize];    public StringBuilder sb = new StringBuilder();}

如果我更改AcceptCallBack方法和StateObject类:

private voID AcceptCallback(IAsyncResult ar){    _manualresetEvent.Set();    Socket Listener = (Socket)ar.AsyncState;    Socket handler = Listener.EndAccept(ar);    try    {        sslStream = new SslStream(new NetworkStream(handler,true));        // try to authenticate        sslStream.AuthenticateAsServer(_cert,false,System.Security.Authentication.SslProtocols.Tls,true);        state.workStream = sslStream;        state.workStream.ReadTimeout = 100000;        state.workStream.WriteTimeout = 100000;        if (state.workStream.IsAuthenticated)        {            state.workStream.BeginRead(state.buffer,ReceiveCallback,state);        }    }    catch (IOException ex)    {        // ıf we get handshake Failed due to an unexpected packet format,this means incoming data is not httpS        // Continue with socket not sslstream        state.workSocket = handler;        handler.BeginReceive(state.buffer,state);    }    StateObject state = new StateObject();    state.workStream = handler;    handler.BeginReceive(state.buffer,state);    Listener.BeginAccept(new AsyncCallback(AcceptCallback),Listener);}public class StateObject{    public Socket workSocket = null;    public SslStream workStream = null;    public const int BufferSize = 1024;    public byte[] buffer = new byte[BufferSize];    public StringBuilder sb = new StringBuilder();}

我可以决定传入的数据类型是http还是httpS,但如果是http,它每次都会被catch块处理,因此会降低应用程序性能.

还有另一种方式吗?

解决方法 如果我理解正确,您有一个端口,客户端可以使用http或httpS进行连接,并且您希望在传输任何数据之前立即知道请求是如何进行的.

在从客户端接收数据之前无法知道这一点. http和httpS是TCP之上的协议,它们不能在较低的协议级别上工作,因此没有标志或任何可以说明使用哪种协议的东西.此外,httpS只是包含在TLS / SSL流中的普通http流.

您必须读取数据并根据使用的协议确定.或者你必须有单独的http和httpS端口,这将使这一点变得微不足道.

要检测它是否是TLS / SSL,您可以查看几个字节并查看其中的内容.The TLS specification表示客户端Hello数据包以协议版本启动,协议版本以两个uint8发送.由于http请求总是将动词作为第一个,因此您可以轻松检查是否有一些第一个字节是字符,然后尝试SSLStream(如果不是).

另请注意,如果您在套接字上启动SSLStream,它可能会从套接字中读取,这将消耗http请求的开头,您无法正常处理它.

所以在你的Accept回调中使用这样的东西:

Socket handler = Listener.EndAccept(ar);byte[] tmp = new byte[2];handler.Receive(tmp,2,SocketFlags.Peek);if (!Char.IsLetter((char)tmp[0]) || !Char.IsLetter((char)tmp[1])){  // Doesn't start with letters,so most likely not http} else {  // Starts with letters,should be http}

如果您想确保它是TLS / SSL,您可以查看this question on SO

总结

以上是内存溢出为你收集整理的c# – 检查请求是否来自套接字侦听器中的HTTP或HTTPS全部内容,希望文章能够帮你解决c# – 检查请求是否来自套接字侦听器中的HTTP或HTTPS所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1243899.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存