【发布时间】:2015-08-15 13:05:26
【问题描述】:
我正在编写一个需要通过 SSL/TLS 进行通信的应用程序。
当我使用以下代码时,设备连接,但我总是读取 0 个字节:
byte[] buffer = new byte[2048];
StringBuilder messageData = new StringBuilder();
int bytes = -1;
do
{
// Read the client's test message.
bytes = sslStream.Read(buffer, 0, buffer.Length);
sslStream.Flush();
// 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);
当我使用此代码时,我能够读取字节但显然无法解码它们。此代码读取了正确的字节数,SSl 出了什么问题,我无法取回任何字节?
var client = server.AcceptTcpClient();
Console.WriteLine("Connected!");
// Get a stream object for reading and writing
var stream = client.GetStream();
// Loop to receive all the data sent by the client.
while (stream.Read(bytes, 0, bytes.Length) != 0)
{
var base64 = Convert.ToBase64String(bytes);
Console.WriteLine(base64);
更大的示例,我认为这是来自 MSDN:
static void ProcessClient(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(serverCertificate,
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);
// Write a message to the client.
byte[] message = Encoding.UTF8.GetBytes("Hello from the server.<EOF>");
Console.WriteLine("Sending hello message.");
sslStream.Write(message);
}
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 client.
// The client signals the end of the message using the
// "<EOF>" marker.
byte[] buffer = new byte[2048];
StringBuilder messageData = new StringBuilder();
int bytes = -1;
do
{
// Read the client's test message.
bytes = sslStream.Read(buffer, 0, buffer.Length);
sslStream.Flush();
// 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 or an empty message.
if (messageData.ToString().IndexOf("<EOF>") != -1)
{
break;
}
} while (bytes != 0);
return messageData.ToString();
}
【问题讨论】:
-
显然 sslStream 变量提供的流发生了一些事情。由于您的问题没有显示您是如何设置 sslStream 的,所以我只能说 ;)
-
我添加了更多代码,这只是我在网上找到的许多示例中的一个,它们都做同样的事情。
-
好吧,复制'n'粘贴示例然后希望一切都能神奇地正常工作总是一个坏主意。请记住,在 MSDN 等文档中给出的代码示例并不意味着是完整、健壮的代码。它们旨在说明或解释一些东西以帮助您了解如何使用特定的类/方法/等...我建议尝试理解示例中给出的代码并进行一些调试找出真正发生的事情。您只是猜测代码读取的是 0 字节,还是您如何确认确实如此? (续...)
-
也许代码根本没有从流中读取,但由于一些异常/错误之前退出了......
-
我想知道代码是否没有使用流,我似乎无法捕获任何异常。我知道代码返回 0 字节或超时,因为我已经在调试器中运行它并查看了变量。我还运行了wireshark,可以看到数据流中有307字节,这是我使用NetworkStream时得到的确切字节数。我只是想了解为什么我无法从 SSLStream 获得任何东西。