【发布时间】: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