3

Recently I was creating an asynchronous ssl socket class. I finished it, and it authenticated with the client successfully but it did not receive the message sent by client correctly.

Here is my code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.IO;

public class Wrapper
{
    public byte[] buffer;
    public SslStream sslStream;
    public object connector;
}

public class Sock
{
    private Dictionary<string, byte> Connections;
    public event Action<Wrapper> AnnounceNewConnection;
    public event Action<Wrapper> AnnounceDisconnection;
    public event Action<byte[], Wrapper> AnnounceReceive;
    private Socket _sock;

    private X509Certificate certificate = X509Certificate.CreateFromCertFile("exportedcertificate.cer");

    public Sock(int port)
    {
        try
        {
            Connections = new Dictionary<string, byte>();
            _sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            _sock.Bind(new IPEndPoint(IPAddress.Any, port));
            _sock.Listen(500);
            _sock.BeginAccept(AcceptConnections, new Wrapper());
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }

    private void AcceptConnections(IAsyncResult result)
    {
        Wrapper wr = (Wrapper)result.AsyncState;
        try
        {
            wr.sslStream = new SslStream(new NetworkStream(_sock.EndAccept(result), true));
            wr.sslStream.BeginAuthenticateAsServer(certificate, EndAuthenticate, wr);

            _sock.BeginAccept(AcceptConnections, new Wrapper());
        }
        catch (Exception e) { Console.WriteLine(e); }
    }

    private void EndAuthenticate(IAsyncResult result)
    {
        Wrapper wr = (Wrapper)result.AsyncState;
        try
        {
            wr.sslStream.EndAuthenticateAsServer(result);
            if (wr.sslStream.IsAuthenticated == true)
            {
                wr.buffer = new byte[65535];
                wr.sslStream.BeginRead(wr.buffer, 0, wr.buffer.Length, ReceiveData, wr);
                AnnounceNewConnection.Invoke(wr);
            }
        }
        catch (Exception e) { Console.WriteLine(e); }
    }

    private void ReceiveData(IAsyncResult result)
    {
        Wrapper wr = (Wrapper)result.AsyncState;
        try
        {
            int size = wr.sslStream.EndRead(result);
            byte[] buffer = new byte[size];
            Buffer.BlockCopy(wr.buffer, 0, buffer, 0, size);
            AnnounceReceive.Invoke(wr.buffer, wr);

            if (wr.sslStream.IsAuthenticated)
                wr.sslStream.BeginRead(wr.buffer, 0, wr.buffer.Length, ReceiveData, wr);
        }
        catch (Exception e) { Console.WriteLine(e); AnnounceDisconnection.Invoke(wr); }
    }
}

So in the code above when I call BeginRead and try to use Console.WriteLine(Encoding.ASCII.GetString(arg1));, I only get alot of empty lines [Note I use the ssl client from the MSDN example to test my server]

I really want to know why it does not correctly receive the message!

Steve Czetty
  • 6,147
  • 9
  • 39
  • 48
Roman Ratskey
  • 5,101
  • 8
  • 44
  • 67
  • I would try using the other BeginAuthenticateAsServer : http://msdn.microsoft.com/en-us/library/ms145073.aspx. The extra settings, like SSLProtocols and clientCertificateRequired might provide different results. This is what I have used, and have had success. – Mausimo Jan 08 '13 at 18:56
  • @Mausimo Can you share if the repo you mention is available – Sahin Jun 02 '22 at 14:37

0 Answers0