我有一个奇怪的问题:我在基于 .net2 的 c# 中编写了一个服务器和客户端,它们通过 .net 2 SslStream 聊天。Cl 和 S 之间有 1 个连接用于发送命令,cl 和 s 之间有一个用于发送文件的连接。
本地一切都在我的Windows机器上运行良好。但是,如果我在我的 Linux 服务器上运行服务器(使用单声道),则在某些情况下共享文件不起作用。我有不同的文件类别,在 3 个中的 2 个中,它的工作,在第三个中,服务器挂起SSLStream.AuthenticateAsServer(....);
并且客户端抛出一个异常,并显示消息“对 SSPI 的调用失败,请参阅内部异常”。内部异常是 System.ComponentModel.Win32Exception,带有消息“收到的消息意外或格式错误。”
我认为我在 linux 上运行它的方式可能是错误的。实际上我使用 VS2012 进行本地开发,当我想把它放在服务器上时,我通过 VS 上传编译的 exe 并使用mono server.exe
它来启动它。但是我也尝试在 Windows 上使用 monodevelop 来编译它(从 monodevelop 编译的东西也可以在本地工作)并在 linux 服务器上使用它,但这以相同的结果结束。
任何帮助将不胜感激。
这是我的缩短代码:
客户:
//gets auth guid before, then it does
Thread Thre = new Thread(sendfile);
Thre.Start(authguid);
private void sendfile(string guid){
TcpClient cl = new TcpClient();
cl.Connect(hostname, 8789);
SslStream Stream = new SslStream(cl.GetStream(), true, new RemoteCertificateValidationCallback(ServerConnector.ValidateServerCertificate));
Stream.AuthenticateAsClient(hostname);//throws the exception
//sends auth guid and file
}
服务器:
public class FServer
{
protected static bool halt = false;
protected List<FConnection> connections;
private TcpListener tcpServer;
private IPEndPoint ipEnde = new IPEndPoint(IPAddress.Any, 8789);
private delegate void dlgAccept();
private dlgAccept accepting;
private IAsyncResult resAccept;
public FServer()
{
tcpServer = new TcpListener(ipEnde);
connections = new List<FConnection>();
tcpServer.Start();
accepting = new dlgAccept(accept);
resAccept = accepting.BeginInvoke(null, null);
}
public void accept()
{
do
{
if (tcpServer.Pending())
connections.Add(new FConnection(tcpServer.AcceptTcpClient(), this));
else
Thread.Sleep(750);
} while (!halt && tcpServer != null);
}
public class FConnection
{
public SslStream stream;
//.....some other properties
public static bool ValidateClientCertificate (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
public FConnection(TcpClient cl, FServer inst)
{
instance = inst;
client = cl;
stream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateClientCertificate), null);
stream.AuthenticateAsServer(instance.mainserver.serverCert, false, SslProtocols.Tls, false);//hangs sometimes on this
if (stream.IsAuthenticated && stream.IsEncrypted)
{
}
else
{
this.Dispose();
}
//auth and receiving file
}
}
}