如何为非阻塞异步套接字

时间:2015-04-26 09:08:04

标签: c# sockets

我有一个监听端口的多线程异步System.Net.Socket。如果我从HTTP收到请求,我没有任何问题,但最近我不得不为我的应用程序添加https支持。

客户端给了我一个.arm个认证文件。它中包含base-64编码的ASCII数据。文件名为cert.arm,它存储在我的解决方案文件夹的根目录中。

以下是我到目前为止使用该证书所做的事情:

using System;
using System.Net;
using System.Threading;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace SocketExample
{
    public class StackOverFlow
    {
        public static ManualResetEvent _manualResetEvent = new ManualResetEvent(false);
        private static X509Certificate2 _cert = X509Certificate2("..\\..\\cert.arm");

        static void Main(string[] args)
        {
            StartListening();
        }

        private static 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 static void AcceptCallback(IAsyncResult ar)
        {
            _manualResetEvent.Set();

            Socket listener = (Socket)ar.AsyncState;

            Socket handler = listener.EndAccept(ar);

            SslStream sslStream = new SslStream(new NetworkStream(handler, false));
            sslStream.AuthenticateAsServer(_cert); // I get exception on this line

            StateObject state = new StateObject();
            state.workSocket = handler;

            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);

            listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
        }

        private static void ReceiveCallback(IAsyncResult result)
        {
            StateObject state = (StateObject)result.AsyncState;
            Socket handler = state.workSocket;

            int numBytesReceived = handler.EndReceive(result);

            if (!handler.Connected)
            {
                handler.Close();
                return;
            }

            if (numBytesReceived > 0)
            {
                state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, numBytesReceived));

                string[] lines = state.sb.ToString().Split('\n');

                if (lines[lines.Length - 1] == "EOF")
                {
                    // All Data Received. Do Something.
                }
                else
                {
                    // All Data is not received. Continue reading...
                    handler.BeginReceive(state.buffer, 0, state.buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), state);
                }
            }
        }
    }
}

认证文件已成功创建。我可以在_cert变量中看到数据。没关系。

问题在于,当我调用AuthenticateAsServer方法时,我得到NotSupportedException,其中说:“服务器模式SSL必须使用带有相关私钥的证书”。

如何将此认证文件应用于我的套接字?

1 个答案:

答案 0 :(得分:2)

您应该使用X509Certificate2代替X509Certificate。它could be the only step required来解决此错误。

X509Certificate2拥有私钥的成员,与X509Certificate不同,SSL套接字需要私钥才能完成其工作。