4

我在这个问题上放了很多信息,因为我不知道什么是相关的

问题:
我正在处理的程序在运行时遇到问题,它会冻结我的整个计算机并且不返回任何错误(我完全无法执行任何 CTRL+ALT+DEL 甚至不起作用的操作)。该程序接受来自 android 客户端的连接,并且 atm android 客户端配置不正确,因此连接被拒绝。

问题:
如何阻止我的程序冻结我的整个机器?

猜想:
我有一些关于发生了什么的理论,但不知道如何解决它们。我已经读到这可能与我在异步工作者中运行单线程进程有关,但我不确定套接字是否是单线程进程。此外,我不完全确定我应该如何处理后台工作人员中的异常,所以我只是让它回退到 RunWorkerCompletedEventArgs 然后从那里检索错误消息。

我尝试过的:
-我尝试在每个地方都放置尝试捕获,然后删除尝试捕获似乎没有任何东西能够捕获此错误
-我检查了我的系统事件日志,除了我的计算机死机后重新启动之外什么都没有显示
-我试图隔离问题,但它可以在从程序开始到我尝试连接的任何时候发生

设置:
我在 Windows 8 pro 机器上运行 Visual Studio 2012 Professional 中的程序。我使用的计算机具有 i7-3770K 3.50GHz 和 32GB 内存。尝试与我建立连接的应用程序是 Android 应用程序,并且在尝试连接时凭据不正确。Visual Studio 正在运行我的主硬盘驱动器并在另一个驱动器上构建项目。

结束语:
说了这么多,有人愿意帮助我吗?如果您需要更多信息,我很乐意提供,请询问。

主要方法:

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Data;
 using System.Windows.Documents;
 using System.Windows.Input;
 using System.Windows.Media;
 using System.Windows.Media.Imaging;
 using System.Windows.Navigation;
 using System.Windows.Shapes;
 using System.ComponentModel;

namespace Server
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class SourceServer : Window
{
    private BackgroundWorker worker = new BackgroundWorker();

    public SourceServer()
    {
        InitializeComponent();

        StartListeningForConnections();
    }

    private void StartListeningForConnections()
    {

        worker.DoWork += new DoWorkEventHandler(worker_DoWork);
        worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
        worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
        worker.WorkerReportsProgress = true;

        if (worker.IsBusy != true)
        {
            worker.RunWorkerAsync();
        }
    }

    private void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        worker.ReportProgress(0, "Source server version 0.0.0.1ib started");
        LoginServer oLoginServer = new LoginServer();
        oLoginServer.StartListening(worker);

    }

    private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        try
        {
            lvOutput.Items.Add(e.UserState.ToString());
        }
        catch (Exception exception)
        {
            lvOutput.Items.Add(exception.StackTrace);
        }
    }

    private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (e.Error != null)
        {
            System.IO.File.WriteAllText(Environment.CurrentDirectory + @"\log.txt", e.Error.StackTrace + " /n " + e.Error.Message);
        }
        else
        {
            MessageBox.Show("Error was null");
        }
        worker.Dispose();
    }
}
}

SSL 套接字连接:

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using System.Threading;
 using System.Net;
 using System.Net.Sockets;
 using System.Windows;
 using System.Windows.Controls;
 using System.ComponentModel;
 using System.Net.Security;
 using System.Security.Cryptography.X509Certificates;
 using MySql.Data.MySqlClient;
 using System.IO;

namespace Server
{
public class LoginServer
{
    // Incoming data from the client.
    public static string data = null;
    public static X509Certificate serverCertificate = null;

    public delegate void UpdateListView(ListView oOutput);

    public void StartListening(BackgroundWorker worker)
    {
        // Data buffer for incoming data.
        byte[] bytes = new Byte[1024];

        // Establish the local endpoint for the socket.
        IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
        IPAddress ipAddress = ipHostInfo.AddressList[1];

        serverCertificate = X509Certificate.CreateFromCertFile(@"server.crt");
        TcpListener oServer = new TcpListener(ipAddress, 12345);


        // Bind the socket to the local endpoint and 
        // listen for incoming connections.

        // Start listening for connections.
        while (true)
        {
            Thread.Sleep(100);
            worker.ReportProgress(0, "Waiting for connection....");

            // Program is suspended while waiting for an incoming connection.
            //Socket handler = listener.Accept();
            oServer.Start();
            TcpClient oClient = oServer.AcceptTcpClient();
            Stream oStream = oClient.GetStream();
            SslStream oSSLStream = new SslStream(oStream);

            data = null;

            // An incoming connection needs to be processed.
            string sUsername = "place holder";
            string sPassword = "place holder";

            while (true)
            {
                bytes = new byte[1024];
                int bytesRec = oSSLStream.Read(bytes, 0, bytes.Length);
                data += Encoding.ASCII.GetString(bytes, 0, bytesRec);

                string[] sCredentials = data.Split("|".ToCharArray()[0]);

                sUsername = sCredentials[0];
                sPassword = sCredentials[1];

                if (data.IndexOf("<EOF>") > -1)
                {
                    break;
                }
            }

            // Show the data on the console.
            worker.ReportProgress(0, "Connection Recieved : ");
            worker.ReportProgress(0, "Username: " + sUsername);
            worker.ReportProgress(0, "Password: " + sPassword);
            worker.ReportProgress(0, "");

            // Echo the data back to the client.
            byte[] msg;
            if (sUsername.Equals("test") && sPassword.Equals("test"))
            {
                msg = Encoding.ASCII.GetBytes("approved<EOF>\n");
                worker.ReportProgress(0, "approved");
                oSSLStream.Write(msg, 0, msg.Length);
            }
            else
            {
                msg = Encoding.ASCII.GetBytes("rejected<EOF>\n");
                worker.ReportProgress(0, "rejected");
                oSSLStream.Write(msg, 0, msg.Length);
            }
        }
    }

    public void VerifyUser()
    {

    }
}
}
4

2 回答 2

2

虽然我看不出有任何理由锁定你的整个计算机,但我确实看到了应用程序可能挂起的几个原因......

除非您的客户端写入,否则您的 SSL 服务器内的 while 循环将永远不会中断

'<EOF>'
到溪流;你必须强迫它去做。我可能会做类似的事情:

while(( bytesRec = oSSLStream.Read(bytes,0,bytes.Length)) > 0 )
{
    // Compare input & break
}

- 您现在拥有的 while 循环(没有线程睡眠)将消耗您所有的系统资源等待......可能永远不会发生的事情。

在一个相关问题中-我注意到您的“DoWork”方法启动了侦听器-但没有为此侦听器启动新线程。这意味着侦听器正在您的接口线程内部运行 - 这将导致接口(可能还有更多......)挂起,直到进程完成 - 如前所述,这可能永远不会发生。

...咳咳...最后一段可能不正确-您正在运行异步工作程序,因此我的第二次评估可能不正确。

干杯,希望这会有所帮助。

于 2013-07-09T22:32:32.073 回答
0

我在 Windows 8 上遇到了一些在 Windows 7(使用 VS2012)上从未见过的挂起问题。正如您所体验的那样,它第一次运行良好,但只锁定了 Visual Studio(而不是我的整台机器),我不得不强制退出。

Visual Studio 2012 Update 4(专注于错误修复和兼容性)似乎修复了它,尽管我没有对此进行科学测试。

注意:截至 2013 年 9 月 1 日,这只是 RC2 版本,因此请检查更新版本,并在 RTM 发生时编辑此答案。

于 2013-09-01T05:19:43.940 回答