Ich versuche, meinen eigenen HTTPS-Proxy-Server zu erstellen. Aus irgendeinem Grund habe ich eine Ausnahme, wenn ich versuche, von sslstream Objekt zu lesen. Hier ist es:C# SSLStream-Lesefunktion löst IOException
Eine nicht behandelte Ausnahme des Typs ‚System.IO.IOException‘ aufgetreten in System.dll
Zusätzliche Informationen: Daten können nicht von der Transportverbindung lesen: Ein Verbindungsversuch, weil die gescheiterten Der verbundene Teilnehmer hat nach einer gewissen Zeit nicht richtig geantwortet oder die Verbindung ist fehlgeschlagen, weil der verbundene Host nicht geantwortet hat.
Hier ist mein Code:
public Server()
{
m_portnumber = 4434;
m_tcplistener = new TcpListener(IPAddress.Any, m_portnumber);
m_cert = createCertificate();
}
public void start()
{
m_tcplistener.Start();
while (true)
{
TcpClient client = m_tcplistener.AcceptTcpClient();
ClientHandler(client);
}
}
private void ClientHandler(TcpClient client)
{
// A client has connected. Create the
// SslStream using the client's network stream.
SslStream sslStream = new SslStream(
client.GetStream(), false);
// Authenticate the server but don't require the client to authenticate.
try
{
sslStream.AuthenticateAsServer(m_cert,
false, SslProtocols.Tls, true);
// Display the properties and settings for the authenticated stream.
DisplaySecurityLevel(sslStream);
DisplaySecurityServices(sslStream);
DisplayCertificateInformation(sslStream);
DisplayStreamProperties(sslStream);
// Set timeouts for the read and write to 5 seconds.
sslStream.ReadTimeout = 5000;
sslStream.WriteTimeout = 5000;
// Read a message from the client.
Console.WriteLine("Waiting for client message...");
string messageData = ReadMessage(sslStream);
Console.WriteLine("Received: {0}", messageData);
}
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.");
sslStream.Close();
client.Close();
return;
}
finally
{
// The client stream will be closed with the sslStream
// because we specified this behavior when creating
// the sslStream.
sslStream.Close();
client.Close();
}
}
static string ReadMessage(SslStream sslStream)
{
// Read the message sent by the server.
// The end of the message is signaled using the
// "<EOF>" marker.
byte[] buffer = new byte[2048];
StringBuilder messageData = new StringBuilder();
int bytes = -1;
do
{
bytes = sslStream.Read(buffer, 0, buffer.Length);
// Use Decoder class to convert from bytes to UTF8
// in case a character spans two buffers.
Decoder decoder = Encoding.UTF8.GetDecoder();
char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
decoder.GetChars(buffer, 0, bytes, chars, 0);
messageData.Append(chars);
// Check for EOF.
if (messageData.ToString().IndexOf("<EOF>") != -1)
{
break;
}
} while (bytes != 0);
return messageData.ToString();
}
static void DisplaySecurityLevel(SslStream stream)
{
Console.WriteLine("Cipher: {0} strength {1}", stream.CipherAlgorithm, stream.CipherStrength);
Console.WriteLine("Hash: {0} strength {1}", stream.HashAlgorithm, stream.HashStrength);
Console.WriteLine("Key exchange: {0} strength {1}", stream.KeyExchangeAlgorithm, stream.KeyExchangeStrength);
Console.WriteLine("Protocol: {0}", stream.SslProtocol);
}
static void DisplaySecurityServices(SslStream stream)
{
Console.WriteLine("Is authenticated: {0} as server? {1}", stream.IsAuthenticated, stream.IsServer);
Console.WriteLine("IsSigned: {0}", stream.IsSigned);
Console.WriteLine("Is Encrypted: {0}", stream.IsEncrypted);
}
static void DisplayStreamProperties(SslStream stream)
{
Console.WriteLine("Can read: {0}, write {1}", stream.CanRead, stream.CanWrite);
Console.WriteLine("Can timeout: {0}", stream.CanTimeout);
}
static void DisplayCertificateInformation(SslStream stream)
{
Console.WriteLine("Certificate revocation list checked: {0}", stream.CheckCertRevocationStatus);
X509Certificate localCertificate = stream.LocalCertificate;
if (stream.LocalCertificate != null)
{
Console.WriteLine("Local cert was issued to {0} and is valid from {1} until {2}.",
localCertificate.Subject,
localCertificate.GetEffectiveDateString(),
localCertificate.GetExpirationDateString());
}
else
{
Console.WriteLine("Local certificate is null.");
}
// Display the properties of the client's certificate.
X509Certificate remoteCertificate = stream.RemoteCertificate;
if (stream.RemoteCertificate != null)
{
Console.WriteLine("Remote cert was issued to {0} and is valid from {1} until {2}.",
remoteCertificate.Subject,
remoteCertificate.GetEffectiveDateString(),
remoteCertificate.GetExpirationDateString());
}
else
{
Console.WriteLine("Remote certificate is null.");
}
}
private static void DisplayUsage()
{
Console.WriteLine("To start the server specify:");
Console.WriteLine("serverSync certificateFile.cer");
Environment.Exit(1);
}
private X509Certificate createCertificate()
{
byte[] c = Certificate.CreateSelfSignCertificatePfx(
"CN=localhost", //host name
DateTime.Parse("2015-01-01"), //not valid before
DateTime.Parse("2020-01-01"), //not valid after
"sslpass"); //password to encrypt key file
using (BinaryWriter binWriter = new BinaryWriter(File.Open(@"cert.pfx", FileMode.Create)))
{
binWriter.Write(c);
}
return new X509Certificate2(@"cert.pfx", "sslpass");
}
}
Das Problem tritt in dieser Zeile auf: bytes = sslStream.Read (buffer, 0, buffer.Length); –
Natürlich tut es das. Sie legen ein Lesezeitlimit fest und MSDN sagt "Wenn die Leseoperation nicht innerhalb der Zeit abgeschlossen wird, die von dieser Eigenschaft angegeben wird, löst die Leseoperation eine IOException aus." Was hast du erwartet? –
(Wenn Sie erwartet haben, EOF mit 'messageData.ToString(). IndexOf (" ") zu erkennen, wird das nur dann erreicht, wenn der Client Ihnen die Bytes' 'sendet. Tut Ihr Client das? Ich vermute, dass Ihr Client ein Webbrowser ist, bezweifle ich. –