之前用socket发送数据到http地址,主要代码如下
public static string PostMsg(string Domain,int port, string hostUrl, string postData)
    {
        byte[] tempby = Encoding.UTF8.GetBytes(postData);
        string sendStr = String.Format("POST {0} HTTP/1.0\r\n", hostUrl);
        sendStr += "Content-Type: application/x-www-form-urlencoded\r\n";
        sendStr += "Accept-Language: zh-cn\r\n";
        sendStr += "User-Agent: mcj\r\n";
        sendStr += "Accept: */*\r\n";
        sendStr += "Accept-Encoding: gzip,deflate\r\n";
        sendStr += "Host: " + Domain+":"+port + "\r\n";
        sendStr += "Content-Length: " + tempby.Length.ToString() + "\r\n";
        sendStr += "Connection: Keep-Alive\r\n\r\n";        sendStr += postData;
        byte[] bytesSendStr = Encoding.UTF8.GetBytes(sendStr); //将发送内容字符串转换成字节byte数组         bool isIpAddress = false;
        try
        {
            IPAddress ip = IPAddress.Parse(Domain);
            isIpAddress = true;
        }
        catch (Exception)
        {
            
            
        }
        ConnectInternet(Domain,port,isIpAddress);
        try
        {
            _socket.Send(bytesSendStr, bytesSendStr.Length, 0);//向主机发送请求  
        }
        catch (Exception ce)
        {
            //Response.Write(ce.Message + "\r\n");
        }        string recvStr = ""; //声明接收返回内容的字符串   
        byte[] recvBytes = new byte[1024];//声明字节数组,一次接收数据的长度为1024字节 
        int bytes = 0;
        while (true)
        {
            bytes = _socket.Receive(recvBytes, recvBytes.Length, 0); //返回实际接收内容的字节数,循环读取,直到接收完所有数据 
            if (bytes <= 0)
                break;
            Encoding gb2312 = Encoding.UTF8;//将读取的字节数转换为字符串   
            recvStr += gb2312.GetString(recvBytes, 0, bytes);
        }        recvStr = recvStr.Substring(recvStr.IndexOf("\r\n\r\n") + 4);        DisConnectInternet();
        return recvStr;
    }
现在需要将http地址改成https地址,哪位大侠帮忙解决一下啊。我的联系方式QQ:154874708,邮箱[email protected]

解决方案 »

  1.   

    参考几个类:SslStream 类NetworkStream 类用Socket 实例化 NetworkStream ,然后用 NetworkStream 实例化 SslStream ,最后用SslStream 收发SSL收据。
      

  2.   

    参考 C# Socket SSL 通讯笔记
      

  3.   


    using System.Net;
    using System.Net.Sockets;
    using System.Net.Security;
    using System.Security.Authentication;
    using System.Security.Cryptography.X509Certificates;
    using System.IO;
    using System.Threading;
            private SslStream mSsl;
            private Socket mSocket ;        public string PostMsg(string Domain, int port, string hostUrl, string postData)
            {
                byte[] tempby = Encoding.UTF8.GetBytes(postData);
                string sendStr = String.Format("POST {0} HTTP/1.0\r\n", hostUrl);
                sendStr += "Content-Type: application/x-www-form-urlencoded\r\n";
                sendStr += "Accept-Language: zh-cn\r\n";
                sendStr += "User-Agent: mcj\r\n";
                sendStr += "Accept: */*\r\n";
                sendStr += "Accept-Encoding: gzip,deflate\r\n";
                sendStr += "Host: " + Domain + ":" + port + "\r\n";
                sendStr += "Content-Length: " + tempby.Length.ToString() + "\r\n";
                sendStr += "Connection: Keep-Alive\r\n\r\n";            sendStr += postData;
                byte[] bytesSendStr = Encoding.UTF8.GetBytes(sendStr); //将发送内容字符串转换成字节byte数组             bool isIpAddress = false;
                try
                {
                    IPAddress ip = IPAddress.Parse(Domain);
                    isIpAddress = true;
                }
                catch (Exception)
                {
                }            ConnectInternet(Domain, port, isIpAddress);            if (!this.Validate("servername"))
                {
                    return null;
                }            try
                {
                    if (this.mSsl.CanWrite)
                    {
                        this.mSsl.Write(bytesSendStr, bytesSendStr.Length, 0);//向主机发送请求  
                    }
                }
                catch (Exception ce)
                {
                    //Response.Write(ce.Message + "\r\n");
                }            string recvStr = ""; //声明接收返回内容的字符串   
                byte[] recvBytes = new byte[1024];//声明字节数组,一次接收数据的长度为1024字节 
                int bytes = 0;
                while (true)
                {
                    if (this.mSsl.CanRead)
                    {
                        bytes = this.mSsl.Read(recvBytes, 0, recvBytes.Length);//返回实际接收内容的字节数,循环读取,直到接收完所有数据 
                    }
                    if (bytes <= 0)
                        break;
                    Encoding gb2312 = Encoding.UTF8;//将读取的字节数转换为字符串   
                    recvStr += gb2312.GetString(recvBytes, 0, bytes);
                }            recvStr = recvStr.Substring(recvStr.IndexOf("\r\n\r\n") + 4);            DisConnectInternet();
                return recvStr;
            }        // The server name must match the name on the server certificate.
            private bool Validate(string serverName)
            {
                // Mark 屏蔽SSL验证
                // return true;            this.mSsl = new SslStream(new NetworkStream(this.mSocket, FileAccess.ReadWrite, true),
                    false,
                    new RemoteCertificateValidationCallback(ValidateServerCertificate),
                    null
                    );            this.mSsl.WriteTimeout = 30000;
                this.mSsl.ReadTimeout = 30000;            try
                {
                    this.mSsl.AuthenticateAsClient(serverName, new X509Certificate2Collection(), SslProtocols.Ssl3, false);
                }
                catch (AuthenticationException e)
                {
                    string strMsg = string.Format("SSL验证失败!\r\nException: {0}", e.Message);
                    if (e.InnerException != null)
                    {
                        strMsg = string.Format("{1}\r\nInner exception: {0}", e.InnerException.Message, strMsg);
                    }
                    Console.WriteLine("Authentication failed - closing the connection.");
                    this.mSsl.Close();
                    this.mSocket.Close();
                    return false;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    return false;
                }
                return true;
            }
            // 验证证书
            private bool ValidateServerCertificate(
               object sender,
               X509Certificate certificate,
               X509Chain chain,
               SslPolicyErrors sslPolicyErrors)
            {
                if (sslPolicyErrors != SslPolicyErrors.None)
                {
                    // Do not allow this client to communicate with unauthenticated servers.
                    return false;
                }
                return true;
            }
      

  4.   

    字符串 += 很耗性能的, 用StringBuilder吧
      

  5.   


    如果不知道servername ,那么参数就传一个空字符串。
    然后 替换如下方法
           // 验证证书
            private bool ValidateServerCertificate(
               object sender,
               X509Certificate certificate,
               X509Chain chain,
               SslPolicyErrors sslPolicyErrors)
            {
                if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateNotAvailable)
                {
                    // Do not allow this client to communicate with unauthenticated servers.
                    return false;
                }
                return true;
            }
      

  6.   

    Validate(string serverName)这个方法里要写的是什么?整个的服务器端url地址?
      

  7.   

    实例化 SslStream 、并进行验证 。MSDN 中有这么几句话:创建 SslStream 后,必须对服务器及客户端(可选)进行身份验证。如果身份验证失败,则将收到一个 AuthenticationException,此时 SslStream 将不再可用。您应关闭此对象并移除对该对象的所有引用,以便垃圾回收器能够收集它。如果身份验证过程(也称为“SSL 握手”)成功,则确定了服务器及客户端(可选)的身份,客户端和服务器可以使用 SslStream 交换消息。
      

  8.   

      // The server name must match the name on the server certificate.
            private bool Validate(string serverName)
            {
                // Mark 屏蔽SSL验证
                // return true;            this.mSsl = new SslStream(new NetworkStream(this.mSocket, FileAccess.ReadWrite, true),
                    false,
                    new RemoteCertificateValidationCallback(ValidateServerCertificate),
                    null
                    );            this.mSsl.WriteTimeout = 30000;
                this.mSsl.ReadTimeout = 30000;            try
                {
                    this.mSsl.AuthenticateAsClient(serverName, new X509Certificate2Collection(), SslProtocols.Ssl3, false);
                }
                catch (AuthenticationException e)
                {
                    string strMsg = string.Format("SSL验证失败!\r\nException: {0}", e.Message);
                    if (e.InnerException != null)
                    {
                        strMsg = string.Format("{1}\r\nInner exception: {0}", e.InnerException.Message, strMsg);
                    }
                    Console.WriteLine("Authentication failed - closing the connection.");
                    this.mSsl.Close();
                    this.mSocket.Close();
                    return false;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    return false;
                }
                return true;
            }上面有的 
      

  9.   

    客户端发送相同的数据 连接http 呢? 接收到的数据是0吗?
      

  10.   

    不是,客户端发送相同的数据连接http可以直接跳转到银行支付页面(项目是类似支付宝接口的)。现在厂商将http地址都换成https了,所以需要改。用你给我的方法连接http也连不上。用我自己的(最上面的代码)可以
      

  11.   

    银行的支付的呀,晕倒。这个肯定是 服务器端要求验证客户端的证书了。参考这段代码   X509CertificateCollection certs = new X509CertificateCollection();
                    X509Certificate cert = X509Certificate.CreateFromCertFile(@"D:\cashcer.cer");
                    certs.Add(cert);
                    try
                    {
                        sslStream.AuthenticateAsClient("MyServer", certs, SslProtocols.Tls, false);
                    }
                    catch (AuthenticationException e)
                    {
                        Console.WriteLine("Exception: {0}", e.Message);
                        if (e.InnerException != null)
                        {
                            Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
                        }
                        Console.WriteLine("Authentication failed - closing the connection.");
                        client.Close();
                        return;
                    }
    再具体的我也帮不了了。
      

  12.   

    X509Certificate cert = X509Certificate.CreateFromCertFile(@"D:\cashcer.cer");这个是 服务器端要验证的证书。还有客户端最好验证 服务器端的证书。
      

  13.   

    我根据网上搜索的资料自己生成了client。cer和Server。cer,上面的D:\cashcer.cer是不是客户端.cer啊,还有这段代码我要放哪里啊
      

  14.   

    X509CertificateCollection certs = new X509CertificateCollection();
                    X509Certificate cert = X509Certificate.CreateFromCertFile(@"D:\cashcer.cer");
                    certs.Add(cert);
                    try
                    {
                        sslStream.AuthenticateAsClient("MyServer", certs, SslProtocols.Tls, false);
                    }
                    catch (AuthenticationException e)
                    {
                        Console.WriteLine("Exception: {0}", e.Message);
                        if (e.InnerException != null)
                        {
                            Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
                        }
                        Console.WriteLine("Authentication failed - closing the connection.");
                        client.Close();
                        return;
                    }这里不是嘛?
      

  15.   


    不是为了分数来的。SSL这我也是刚学会的、只是顺手帮一下而已。
      

  16.   

    利用socket实现HTTPS上面的列子能完整的实现吗
    如果现在不需要客服端 的证书