【问题标题】:Winform + TCPListener not loading properlyWinform + TCPListener 未正确加载
【发布时间】:2018-04-14 22:20:09
【问题描述】:

我有一个 Windows 窗体,它在与 tcpclient 建立连接之前无法工作。然后它就不能正常工作(它一直挂着,就像被冻结了一样)。

这是 TCPListener 的代码:

using System;
using System.Drawing;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Forms;
namespace ServerChatGUI
{
public partial class Form1 : Form
{
    public Timer timer1;
    public TcpListener myList = null;

    public string EncryptionKey = GetHashedKey("Alexandros");

    public Form1()
    {
        InitializeComponent();
        try
        {
            IPAddress ipAd = IPAddress.Parse("172.17.1.241");
            // use local m/c IP address, and 
            // use the same in the client

            /* Initializes the Listener */
            myList = new TcpListener(ipAd, 8001);

            /* Start Listeneting at the specified port */
            myList.Start();


            Socket s = myList.AcceptSocket();
            this.Show();

            chatDisplay_txtbox.AppendText("Connection accepted from " + s.RemoteEndPoint + "\n");
            connection_lbl.Text = "Connected";
            connection_lbl.ForeColor = Color.Green;


            //InitTimer();
        }

        catch (Exception e)
        {
            Console.WriteLine("Error..... " + e.ToString());
        }


    }

    public static string GetHashedKey(string text)
    {
        byte[] bytes = Encoding.UTF8.GetBytes(text);
        SHA256Managed hashstring = new SHA256Managed();
        byte[] hash = hashstring.ComputeHash(bytes);
        string hashString = string.Empty;
        int cntr = 0;
        foreach (byte x in hash)
        {
            if (cntr == 1)
            {
                cntr = 0;
            }
            else
            {
                hashString += String.Format("{0:x2}", x);
                cntr++;
            }
        }
        return hashString;
    }

    //Encrypting a string
    public static string TxtEncrypt(string inText, string key)
    {
        byte[] bytesBuff = Encoding.UTF8.GetBytes(inText);
        using (Aes aes = Aes.Create())
        {
            Rfc2898DeriveBytes crypto = new Rfc2898DeriveBytes(key, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
            aes.Key = crypto.GetBytes(32);
            aes.IV = crypto.GetBytes(16);
            using (MemoryStream mStream = new MemoryStream())
            {
                using (CryptoStream cStream = new CryptoStream(mStream, aes.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cStream.Write(bytesBuff, 0, bytesBuff.Length);
                    cStream.Close();
                }
                inText = Convert.ToBase64String(mStream.ToArray());
            }
        }
        return inText;
    }

    //Decrypting a string
    public static string TxtDecrypt(string cryptTxt, string key)
    {
        cryptTxt = cryptTxt.Replace(" ", "+");
        cryptTxt = cryptTxt.Replace("\0", "");
        byte[] bytesBuff = Convert.FromBase64String(cryptTxt);
        using (Aes aes = Aes.Create())
        {
            Rfc2898DeriveBytes crypto = new Rfc2898DeriveBytes(key, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
            aes.Key = crypto.GetBytes(32);
            aes.IV = crypto.GetBytes(16);
            using (MemoryStream mStream = new MemoryStream())
            {
                using (CryptoStream cStream = new CryptoStream(mStream, aes.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cStream.Write(bytesBuff, 0, bytesBuff.Length);
                    cStream.Close();
                }
                cryptTxt = Encoding.UTF8.GetString(mStream.ToArray());
            }
        }
        return cryptTxt;
    }


    private void button1_Click(object sender, EventArgs e)
    {
        Socket s = myList.AcceptSocket();
        chatDisplay_txtbox.AppendText("Me:\t ");
        chatDisplay_txtbox.AppendText(inMessage_txtbox.Text + "\n");


        String str = TxtEncrypt(inMessage_txtbox.Text, EncryptionKey);
        s.Send(Encoding.UTF8.GetBytes(str));

    }

    public void InitTimer()
    {
        timer1 = new Timer();
        timer1.Tick += new EventHandler(timer1_Tick);
        timer1.Interval = 200; // in miliseconds
        timer1.Start();
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        Socket s = myList.AcceptSocket();
        if (s.Available > 0)
        {
            byte[] b = new byte[s.ReceiveBufferSize];
            int k = s.Receive(b);
            string msg = "";
            chatDisplay_txtbox.AppendText("Other:\t");
            for (int i = 0; i < k; i++)
            {
                msg += Convert.ToChar(b[i]);
            }
            chatDisplay_txtbox.AppendText(TxtDecrypt(msg, EncryptionKey) + "\n");
        }
    }
}
}

这是 TCP 客户端的代码(这个确实有效):

using System;
using System.Drawing;
using System.IO;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Forms;
namespace ChatClientGUI
{
public partial class Form1 : Form
{
    public string EncryptionKey = GetHashedKey("Alexandros");
    public TcpClient tcpclnt = null;
    public bool cntrl = false;
    public Timer timer1;
    public Form1()
    {
        InitializeComponent();
        try
        {
            tcpclnt = new TcpClient();
            chatDisplayer_txtbox.AppendText("this is the beginning of your chat\n");
            tcpclnt.Connect("172.17.1.241", 8001);
            // use the ipaddress as in the server program



            displayConnection_lbl.Text = "Connected";
            displayConnection_lbl.ForeColor = Color.Green;

            InitTimer();
        }
        catch (Exception e)
        {
            Console.WriteLine("Error..... " + e.ToString());
        }

    }

    public static string GetHashedKey(string text)
    {
        byte[] bytes = Encoding.UTF8.GetBytes(text);
        SHA256Managed hashstring = new SHA256Managed();
        byte[] hash = hashstring.ComputeHash(bytes);
        string hashString = string.Empty;
        int cntr = 0;
        foreach (byte x in hash)
        {
            if (cntr == 1)
            {
                cntr = 0;
            }
            else
            {
                hashString += String.Format("{0:x2}", x);
                cntr++;
            }
        }
        return hashString;
    }

    //Encrypting a string
    public static string TxtEncrypt(string inText, string key)
    {
        byte[] bytesBuff = Encoding.UTF8.GetBytes(inText);
        using (Aes aes = Aes.Create())
        {
            Rfc2898DeriveBytes crypto = new Rfc2898DeriveBytes(key, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
            aes.Key = crypto.GetBytes(32);
            aes.IV = crypto.GetBytes(16);
            using (MemoryStream mStream = new MemoryStream())
            {
                using (CryptoStream cStream = new CryptoStream(mStream, aes.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cStream.Write(bytesBuff, 0, bytesBuff.Length);
                    cStream.Close();
                }
                inText = Convert.ToBase64String(mStream.ToArray());
            }
        }
        return inText;
    }

    //Decrypting a string
    public static string TxtDecrypt(string cryptTxt, string key)
    {
        cryptTxt = cryptTxt.Replace(" ", "+");
        byte[] bytesBuff = Convert.FromBase64String(cryptTxt);
        using (Aes aes = Aes.Create())
        {
            Rfc2898DeriveBytes crypto = new Rfc2898DeriveBytes(key, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
            aes.Key = crypto.GetBytes(32);
            aes.IV = crypto.GetBytes(16);
            using (MemoryStream mStream = new MemoryStream())
            {
                using (CryptoStream cStream = new CryptoStream(mStream, aes.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cStream.Write(bytesBuff, 0, bytesBuff.Length);
                    cStream.Close();
                }
                cryptTxt = Encoding.UTF8.GetString(mStream.ToArray());
            }
        }
        return cryptTxt;
    }

    private void SendMessage_btn_Click(object sender, EventArgs e)
    {
        chatDisplayer_txtbox.AppendText("Me:\t ");
        chatDisplayer_txtbox.AppendText(inMessage_txtbox.Text + "\n");

        String str = TxtEncrypt(inMessage_txtbox.Text, EncryptionKey);
        Stream stm = tcpclnt.GetStream();

        byte[] ba = Encoding.UTF8.GetBytes(str);

        stm.Write(ba, 0, ba.Length);
        cntrl = true;
    }


    public void InitTimer()
    {
        timer1 = new Timer();
        timer1.Tick += new EventHandler(timer1_Tick);
        timer1.Interval = 200; // in miliseconds
        timer1.Start();
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        if (tcpclnt.Available > 0)
        {
            Stream stm = tcpclnt.GetStream();

            byte[] bb = new byte[tcpclnt.ReceiveBufferSize];

            int k = stm.Read(bb, 0, tcpclnt.ReceiveBufferSize);
            string msg = "";
            chatDisplayer_txtbox.AppendText("Other:\t");
            for (int i = 0; i < k; i++)
            {
                msg += Convert.ToChar(bb[i]);
            }
            chatDisplayer_txtbox.AppendText(TxtDecrypt(msg, EncryptionKey) + "\n"); ;
        }
    }

}
}

据我所知,它一旦挂起似乎与计时器有关,但同样的计时器在 TCP 客户端中工作。

我真的很迷茫,我想知道我在哪里犯了错误以及为什么。 谁能帮我理解为什么它不起作用?

【问题讨论】:

  • 您在主 ( UI ) 线程上做所有事情,这就是您的应用程序冻结的原因。了解异步操作和线程。
  • 我读过关于异步的文章,但我不太明白我没有使用它。而且,它对客户有用。为什么它对听众不起作用?
  • 不要等待,不要以 GUI 形式的 ctor 或事件处理程序进行像 accept() 这样的阻塞调用。

标签: c# .net sockets security tcp


【解决方案1】:
using System;
using System.Drawing;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Forms;
namespace ServerChatGUI
{
public partial class Form1 : Form
{
    public static TcpListener myList = null;
    public static Socket s = null;
    public static string EncryptionKey = GetHashedKey("Alexandros");
    public static TextBox chatBox = null;

    public Form1()
    {
        InitializeComponent();
        try
        {
            chatBox = chatDisplay_txtbox;
            IPAddress ipAd = IPAddress.Parse("192.168.1.12");
            // use local m/c IP address, and
            // use the same in the client

            /* Initializes the Listener */
            myList = new TcpListener(ipAd, 8001);

            /* Start Listeneting at the specified port */
            myList.Start();

            s = myList.AcceptSocket();

            chatDisplay_txtbox.AppendText("Connection accepted from " + s.RemoteEndPoint + "\n");
            connection_lbl.Text = "Connected";
            connection_lbl.ForeColor = Color.Green;

            System.Threading.Timer t = new System.Threading.Timer(TimerCallback, null, 0, 2000);
        }
        catch (Exception e)
        {
            Console.WriteLine("Error..... " + e.ToString());
        }
    }

    public static string GetHashedKey(string text)
    {
        byte[] bytes = Encoding.UTF8.GetBytes(text);
        SHA256Managed hashstring = new SHA256Managed();
        byte[] hash = hashstring.ComputeHash(bytes);
        string hashString = string.Empty;
        int cntr = 0;
        foreach (byte x in hash)
        {
            if (cntr == 1)
            {
                cntr = 0;
            }
            else
            {
                hashString += String.Format("{0:x2}", x);
                cntr++;
            }
        }
        return hashString;
    }

    //Encrypting a string
    public static string TxtEncrypt(string inText, string key)
    {
        byte[] bytesBuff = Encoding.UTF8.GetBytes(inText);
        using (Aes aes = Aes.Create())
        {
            Rfc2898DeriveBytes crypto = new Rfc2898DeriveBytes(key, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
            aes.Key = crypto.GetBytes(32);
            aes.IV = crypto.GetBytes(16);
            using (MemoryStream mStream = new MemoryStream())
            {
                using (CryptoStream cStream = new CryptoStream(mStream, aes.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cStream.Write(bytesBuff, 0, bytesBuff.Length);
                    cStream.Close();
                }
                inText = Convert.ToBase64String(mStream.ToArray());
            }
        }
        return inText;
    }

    //Decrypting a string
    public static string TxtDecrypt(string cryptTxt, string key)
    {
        cryptTxt = cryptTxt.Replace(" ", "+");
        cryptTxt = cryptTxt.Replace("\0", "");
        byte[] bytesBuff = Convert.FromBase64String(cryptTxt);
        using (Aes aes = Aes.Create())
        {
            Rfc2898DeriveBytes crypto = new Rfc2898DeriveBytes(key, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
            aes.Key = crypto.GetBytes(32);
            aes.IV = crypto.GetBytes(16);
            using (MemoryStream mStream = new MemoryStream())
            {
                using (CryptoStream cStream = new CryptoStream(mStream, aes.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cStream.Write(bytesBuff, 0, bytesBuff.Length);
                    cStream.Close();
                }
                cryptTxt = Encoding.UTF8.GetString(mStream.ToArray());
            }
        }
        return cryptTxt;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        chatDisplay_txtbox.AppendText("Me:\t ");
        chatDisplay_txtbox.AppendText(inMessage_txtbox.Text + "\n");

        String str = TxtEncrypt(inMessage_txtbox.Text, EncryptionKey);
        s.Send(Encoding.UTF8.GetBytes(str));
        GC.Collect();
    }

    private void TimerCallback(Object o)
    {
        if (s.ReceiveBufferSize > 0)
        {
            byte[] b = new byte[s.ReceiveBufferSize];
            int k = s.Receive(b);
            string msg = "";
            chatDisplay_txtbox.Invoke(new Action(() => chatDisplay_txtbox.AppendText("Other:\t")));
            for (int i = 0; i < k; i++)
            {
                msg += Convert.ToChar(b[i]);
            }
            chatDisplay_txtbox.Invoke(new Action(() => chatDisplay_txtbox.AppendText(TxtDecrypt(msg, EncryptionKey) + "\n")));
            GC.Collect();
        }
     }
  }
}

此代码可以正常工作。问题出在计时器上。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2021-05-25
    • 2019-11-01
    • 2017-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多