【发布时间】:2017-02-02 12:51:07
【问题描述】:
我目前正在使用我们设计用于与 Xamarin 移动应用程序通信的服务器应用程序。我们正在使用一个旧的消息传递库,它与TcpClient 建立连接并保持连接打开(每 3 秒发送一次心跳消息)。我们通过用SslStream 包装TcpClient 流将SSL 添加到库中。我们已经在 Windows 上运行了服务器应用程序,它运行良好,但我们的最终目标是 BeagleBoneBlack 上的 Mono。
但是,当我们在移动应用端关闭流和客户端,然后尝试重新启动新连接时,SslStream.AuthenticateAsServer(...) 将不会在服务器上完成。但是,如果我完全关闭移动应用程序,服务器会抛出异常。此时,我重新打开应用程序,并且可以毫无问题地重新连接。
因此,似乎在应用程序或服务器端都没有关闭低级别的东西。奇怪的是,当服务器在 Windows 上运行时,我在两者上运行完全相同的代码并且我没有遇到问题。
这是我关闭/处理流的代码
public async Task Disconnect()
{
if (!UseAsync)
{
semaphore.Wait();
}
try
{
if (UseSSL)
{
SslStream?.Close();
}
Client?.GetStream()?.Close();
Client?.Close();
}
catch (Exception ex) // Assuming we had an exception from trying to close the sslstream
{
logger.Error(ex, "Did not close/dispose correctly: {0}", ex.ToString());
}
finally
{
SslStream = null;
Client = null;
if (!UseAsync)
{
semaphore.Release();
}
}
}
编辑:这应该不重要,因为问题似乎出在服务器的某个地方,并且客户端和服务器的 ssl 代码几乎相同,但如果有人问,这里是客户端断开代码
public async Task Disconnect()
{
try
{
if (UseSSL)
{
_sslStream?.Close();
}
Client?.GetStream()?.Close();
Client?.Close();
}
catch // Assuming we had an exception from trying to close the sslstream
{
// Ignore exceptions since we've already closed them
}
finally
{
_sslStream = null;
Client = null;
}
}
编辑 2
还应注意,我发现至少有一个bug report 看起来与我正在处理的问题相同。从这个错误报告中看,它并没有得到解决,但我发现其他报告似乎反映了单声道框架中的类似问题,并且已经解决。此外,我添加了代码以在连接蚂蚁之后从客户端发送一些“虚拟”数据,它似乎没有影响。
编辑 3:我最终在客户端收到此异常
System.IO.IOException: The authentication or decryption has failed. ---> System.IO.IOException: The authentication or decryption has failed. ---> Mono.Security.Protocol.Tls.TlsException: The authentication or decryption has failed.
at Mono.Security.Protocol.Tls.RecordProtocol.EndReceiveRecord (System.IAsyncResult asyncResult) [0x0003a] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs:430
at Mono.Security.Protocol.Tls.SslClientStream.SafeEndReceiveRecord (System.IAsyncResult ar, System.Boolean ignoreEmpty) [0x00000] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslClientStream.cs:256
at Mono.Security.Protocol.Tls.SslClientStream.NegotiateAsyncWorker (System.IAsyncResult result) [0x00360] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslClientStream.cs:533
【问题讨论】: