using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using System.Net; using System.Net.Sockets; using System.IO; using System.IO.Compression; using System.Security.Cryptography; namespace IMClientbyTCPinLAN { public partial class Form1 : Form { TcpClient tcpClient; private NetworkStream Stream; private static string CLOSED = "closed"; private static string CONNECTED = "connected"; private string state = CLOSED; private bool stopFlag; AesCryptoServiceProvider myAes; public Form1() { InitializeComponent(); Control.CheckForIllegalCrossThreadCalls = false; txtHost.Text = getIPAddress(); txtPort.Text = "9988"; try { // Create a new instance of the AesCryptoServiceProvider class. // This generates a new key and initialization vector (IV). myAes = new AesCryptoServiceProvider(); MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); SHA256CryptoServiceProvider sha256 = new SHA256CryptoServiceProvider(); myAes.Key = sha256.ComputeHash(Encoding.UTF8.GetBytes("Copyright(R) xiesir@gmail.com, 2015-2018, ;-)")); myAes.IV = md5.ComputeHash(Encoding.UTF8.GetBytes("Copyright 2015-2018")); } catch (Exception e) { Console.WriteLine("Error: {0}", e.Message); } } private void btnLogin_Click(object sender, EventArgs e) { if (state == CONNECTED) return; if (txtUserName.Text.Length == 0) { MessageBox.Show("请输入您的呢称!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); txtUserName.Focus(); return; } try { tcpClient = new TcpClient(); tcpClient.Connect(IPAddress.Parse(txtHost.Text), Int32.Parse(txtPort.Text)); Stream = tcpClient.GetStream(); string cmd = "CONN|" + txtUserName.Text + "|"; // Non-Encrypt byte[] outbytes = Encoding.Default.GetBytes(cmd.ToCharArray()); // Encrypt //byte[] outbytes = EncryptStringToBytes_Aes(cmd, myAes.Key, myAes.IV); Stream.Write(outbytes, 0, outbytes.Length); Thread thread = new Thread(new ThreadStart(ServerResponse)); thread.Start(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } private void btnExit_Click(object sender, EventArgs e) { if (state == CONNECTED) { string message = "EXIT|" + txtUserName.Text + "|"; // Non-Encrypt Byte[] outbytes = Encoding.Default.GetBytes(message.ToCharArray()); // Encrypt //byte[] outbytes = EncryptStringToBytes_Aes(message, myAes.Key, myAes.IV); Stream.Write(outbytes, 0, outbytes.Length); state = CLOSED; stopFlag = true; lstUsers.Items.Clear(); } } private void btnSend_Click(object sender, EventArgs e) { try { if (!cbPrivate.Checked) { string message = "CHAT|" + txtUserName.Text + ":" + this.tbSendContent.Text + "|"; this.tbSendContent.Text = ""; this.tbSendContent.Focus(); // Non-Encrypt Byte[] outbytes = Encoding.Default.GetBytes(message.ToCharArray()); // Encrypt //byte[] outbytes = EncryptStringToBytes_Aes(message, myAes.Key, myAes.IV); Stream.Write(outbytes, 0, outbytes.Length); } else { if (lstUsers.SelectedIndex == -1) { MessageBox.Show("请在列表中选择一个用户", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } string receiver = lstUsers.SelectedItem.ToString(); string message = "PRIV|" + txtUserName.Text + "|" + receiver + "|" + this.tbSendContent.Text + "|"; tbSendContent.Text = ""; tbSendContent.Focus(); // Non-Encrypt byte[] outbytes = Encoding.Default.GetBytes(message.ToCharArray()); // Encrypt //byte[] outbytes = EncryptStringToBytes_Aes(message, myAes.Key, myAes.IV); Stream.Write(outbytes, 0, outbytes.Length); } } catch { tbMsg.AppendText("网络发生错误"); } } private void ServerResponse() { byte[] buff = new byte[1024]; string msg; int len; try { if (!Stream.CanRead) return; stopFlag = false; while (!stopFlag) { len = Stream.Read(buff, 0, buff.Length); if (len < 1) { Thread.Sleep(200); continue; } // Non-Decrypt msg = Encoding.Default.GetString(buff, 0, len); // Decrypt //msg = DecryptStringFromBytes_Aes(buff, myAes.Key, myAes.IV); msg.Trim(); string[] tokens = msg.Split(new Char[] { '|' }); //tokens[0]中保存了命令标志符(LIST或JOIN或QUIT) if (tokens[0].ToUpper() == "OK") add("成功进入"); else if (tokens[0].ToUpper() == "ERR") add("命令执行错误:" + tokens[1]); else if (tokens[0] == "LIST") { lstUsers.Items.Clear(); for (int i = 1; i < tokens.Length - 1; i++) lstUsers.Items.Add(tokens[i].Trim()); } else if (tokens[0] == "JOIN") { add("用户: " + tokens[1] + " 进入聊天室"); lstUsers.Items.Add(tokens[1]); if (txtUserName.Text == tokens[1]) state = CONNECTED; } else if (tokens[0] == "QUIT") { if (lstUsers.Items.IndexOf(tokens[1]) > -1) lstUsers.Items.Remove(tokens[1]); add("用户: " + tokens[1] + " 已经离开"); } else add(msg); } //关闭连接 tcpClient.Close(); } catch { add("网络发生错误"); } } delegate void addCallback(string text); private void add(string text) { if (tbMsg.InvokeRequired) { while (!tbMsg.IsHandleCreated) { //解决窗体关闭时出现“访问已释放句柄“的异常 if (tbMsg.Disposing || tbMsg.IsDisposed) return; } addCallback d = new addCallback(add); tbMsg.Invoke(d, new object[] { text }); } else { tbMsg.AppendText(text + Environment.NewLine); } } private string getIPAddress() { //获得本机局域网IP地址 IPAddress ip = null; IPAddress[] AddressList = Dns.GetHostEntry(Dns.GetHostName()).AddressList; if (AddressList.Length < 1) return ""; for (int i = 0; i < AddressList.Length; i++) if (AddressList[i].AddressFamily == AddressFamily.InterNetwork) // 获取 IPv4 地址 { ip = AddressList[i]; break; } return ip.ToString(); } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { try { btnExit_Click(sender, e); } catch (Exception) { Application.Exit(); } } static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV) { // Check arguments. if (plainText == null || plainText.Length <= 0) throw new ArgumentNullException("plainText"); if (Key == null || Key.Length <= 0) throw new ArgumentNullException("Key"); if (IV == null || IV.Length <= 0) throw new ArgumentNullException("Key"); byte[] encrypted; // Create an AesCryptoServiceProvider object // with the specified key and IV. using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider()) { aesAlg.Key = Key; aesAlg.IV = IV; // Create a decrytor to perform the stream transform. ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); // Create the streams used for encryption. using (MemoryStream msEncrypt = new MemoryStream()) { using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) { using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) { //Write all data to the stream. swEncrypt.Write(plainText); swEncrypt.Flush(); } encrypted = msEncrypt.ToArray(); } } } // Return the encrypted bytes from the memory stream. return encrypted; } static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV) { // Check arguments. if (cipherText == null || cipherText.Length <= 0) throw new ArgumentNullException("cipherText"); if (Key == null || Key.Length <= 0) throw new ArgumentNullException("Key"); if (IV == null || IV.Length <= 0) throw new ArgumentNullException("IV"); // Declare the string used to hold // the decrypted text. string plaintext = null; // Create an AesCryptoServiceProvider object // with the specified key and IV. using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider()) { aesAlg.Key = Key; aesAlg.IV = IV; // Create a decrytor to perform the stream transform. ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); // Create the streams used for decryption. using (MemoryStream msDecrypt = new MemoryStream(cipherText)) { using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) { using (StreamReader srDecrypt = new StreamReader(csDecrypt)) { // Read the decrypted bytes from the decrypting stream // and place them in a string. plaintext = srDecrypt.ReadToEnd(); } } } } return plaintext; } } }
浙公网安备 33010602011771号