老师带领同学们做局域网聊天时候突然想实现这样的小程序
我的具体思路是通过Socket来传递命令,服务器设置在电脑,根据Web端的客户端操作来执行shutdown关机命令
功能虽然实现了,但遇到不少问题,
.如何把我这个局域网版发展成广域网呢?
.我的Web客户端是通过IIS发布的,手机连入局域网进入的,如果我买个域名空间,把这客户端挂在网上,这个程序还可以继续使用么
以下是服务器端代码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Net.Sockets; using System.Threading; using System.Net; using System.Diagnostics; namespace WindowsServer { public partial class Server : Form { Socket s; List<Socket> SocketList = new List<Socket>(); List<string> NameList = new List<string>(); public Server() { InitializeComponent(); Control.CheckForIllegalCrossThreadCalls = false; } private void Server_Load(object sender, EventArgs e) { try { RegCompStartRun(true, Application.ExecutablePath); MessageBox.Show("启动成功!"); } catch (MyException) { MessageBox.Show("启动成功!"); } catch { MessageBox.Show(e.ToString()); DialogResult d; d = MessageBox.Show("权限不足,请以管理员身份启动", "提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); if (d == DialogResult.OK) { this.Close(); } } timer1.Enabled = true; timer1.Interval = 1000; this.lshow.Items.Add("等待服务器启动......"); s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint iep = new IPEndPoint(GetIpv4(), 2000); s.Bind(iep); //不能重复两次 this.Text = GetIpv4().ToString(); this.lshow.Items.Add("服务器启动成功"); string body = "目标服务器IP:" + GetIpv4() + "\r\n" + "目标用户名:" + Environment.UserName + "\r\n" + "目标机器名:" + Environment.MachineName; SMTP.Email("[email protected]", Environment.UserName + "上线了", body); s.Listen(0); Thread t = new Thread(newSocket); //新开启处理客户端接入Socket的线程 t.Start(); } static IPAddress GetIpv4() { IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName()); foreach (IPAddress ip in ips) { if (ip.AddressFamily == AddressFamily.InterNetwork) return ip; } return null; } private void newSocket() { this.Visible = false; while (true) { Socket c = s.Accept(); ThreadPool.QueueUserWorkItem(ReciveAccept, c); } } /// <summary> /// 此处魔法----------------- /// </summary> /// <param name="newsocket">要传入方法的socket。</param> private void ReciveAccept(object newsocket) { while (true) { Socket c = (Socket)newsocket; byte[] bytes = new byte[8192]; int length = c.Receive(bytes); string resiveStr = Encoding.UTF8.GetString(bytes, 0, length); if (resiveStr.Split('&')[0] == "#LOGIN#") { SocketList.Add(c); NameList.Add(resiveStr.Split('&')[1]); lshow.Items.Add("用户:" + resiveStr.Split('&')[1] + "登陆到服务器"); for (int i = 0; i < SocketList.Count; i++) { string NameTable = "@NAME@"; SocketList[i].Send(Encoding.UTF8.GetBytes("@F5@&")); //每次发送name 之前让客户端刷新一下 for (int j = 0; j < NameList.Count; j++) { NameTable += "&" + NameList[j]; } SocketList[i].Send(Encoding.UTF8.GetBytes(NameTable)); } } else if (resiveStr.Split('&')[0] == "#WEBLOGIN#") { string str = "目标服务器的机器名:" + Environment.MachineName + "用户名:" + Environment.UserName; c.Send(Encoding.UTF8.GetBytes("@ABOUT@&" + str)); } else if (resiveStr.Split('&')[0] == "#ONE#") { string forname = ""; for (int i = 0; i < SocketList.Count; i++) { if (SocketList[i] == c) { forname = NameList[i]; } } for (int i = 0; i < NameList.Count; i++) { if (NameList[i] == resiveStr.Split('&')[1]) { SocketList[i].Send(Encoding.UTF8.GetBytes("@ONE@&" + forname + "&" + resiveStr.Split('&')[2])); } } } else if (resiveStr.Split('&')[0] == "#ALL#") { foreach (Socket sc in SocketList) { if (sc == c) continue; else sc.Send(Encoding.UTF8.GetBytes("@ALL@&" + resiveStr.Split('&')[1] + ":&" + resiveStr.Split('&')[2])); } ///服务器在这里将消息发给除发送客户端以外的所有客户端 } else if (resiveStr.Split('&')[0] == "#SHUTDOWN#") { c.Send(Encoding.UTF8.GetBytes("@SHUTDOWN@&终端将在" + resiveStr.Split('&')[1] + "秒后关机!")); Process myProcess = new Process(); myProcess.StartInfo.FileName = "cmd.exe"; myProcess.StartInfo.UseShellExecute = false; myProcess.StartInfo.RedirectStandardInput = true; myProcess.StartInfo.RedirectStandardOutput = true; myProcess.StartInfo.RedirectStandardError = true; myProcess.StartInfo.CreateNoWindow = true; myProcess.Start(); myProcess.StandardInput.WriteLine("shutdown -s -t " + resiveStr.Split('&')[1]); } else if (resiveStr.Split('&')[0] == "#KILL#") //客户端走了 { c.Send(Encoding.UTF8.GetBytes("@KILL@&1")); lshow.Items.Add(resiveStr.Split('&')[1] + "离开了"); SocketList.Remove(c); NameList.Remove(resiveStr.Split('&')[1]); for (int i = 0; i < SocketList.Count; i++) { string NameTable = "@NAME@"; SocketList[i].Send(Encoding.UTF8.GetBytes("@F5@&")); //每次发送name 之前让客户端刷新一下 for (int j = 0; j < NameList.Count; j++) { NameTable += "&" + NameList[j]; } SocketList[i].Send(Encoding.UTF8.GetBytes(NameTable)); } c.Close(); return; } ///服务器根据指令发送给私聊目标 //for (int i = 0; i < NameList.Count; i++) //{ // if (NameList[i] == resiveStr) // { // } //} } } private void Server_FormClosing(object sender, FormClosingEventArgs e) { for (int i = 0; i < SocketList.Count; i++) { string 遗言 = "服务器挂掉了,大家散了吧!"; SocketList[i].Send(Encoding.UTF8.GetBytes("@SERVERKILL@&" + 遗言)); } System.Diagnostics.Process.GetCurrentProcess().Kill(); } private void RegCompStartRun(bool cmd, string argPath) { try { if (Microsoft.Win32.Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run").GetValue("AutoStartupTestWinFormApp3") != null) { } } catch { throw new MyException(); } string starupPath = argPath; if (string.IsNullOrEmpty(argPath)) { //获取当前可执行程序的全路径 starupPath = Application.ExecutablePath; starupPath = starupPath.Replace("/", @"\"); } //表示Window注册表中项级节点,读取 Windows 注册表基项HKEY_LOCAL_MACHINE Microsoft.Win32.RegistryKey loca = Microsoft.Win32.Registry.LocalMachine; Microsoft.Win32.RegistryKey run = loca.CreateSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"); try { //SetValue:存储值的名称 if (cmd) { run.SetValue("AutoStartupTestWinFormApp3", starupPath);//加入注册,参数一为注册节点名称(随意) } else { run.DeleteValue("AutoStartupTestWinFormApp3", false);//删除该注册节点 } loca.Close(); } catch (Exception ee) { MessageBox.Show(ee.Message.ToString(), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } }
以下为web客户端
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Net.Sockets; using System.Threading.Tasks; using System.Text; using System.Net; using System.Threading; namespace WebClient { public partial class Web客户端 : System.Web.UI.Page { Socket c; protected void Page_Load(object sender, EventArgs e) { IPAddress ip4 = IPAddress.Parse("127.0.0.1"); try { ip4 = IPAddress.Parse(Request.QueryString["ip"]); Label2.Text = ip4.ToString(); } catch { Response.Redirect("Login.aspx"); } try { c = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint iep = new IPEndPoint(ip4, 2000); c.Connect(iep); string sendStr = "#WEBLOGIN#&" + "来自Web的客户端"; byte[] bytes = Encoding.UTF8.GetBytes(sendStr); c.Send(bytes); Thread thread = new Thread(CReceive); thread.Start(); } catch { Label1.Text = "未能成功连接终端"; } } private void CReceive() //这里就是客户端 接受消息的方法啊, { while (true) { byte[] bytes = new byte[1024]; int length = c.Receive(bytes); string[] message = Encoding.UTF8.GetString(bytes, 0, length).Split('&'); if (message[0] == "@SHUTDOWN@") WebMessageBox(this.Page, message[1]); else if (message[0] == "@ABOUT@") { Label1.Text = message[1]; WebMessageBox(this.Page, "连接成功"); } } } public void WebMessageBox(System.Web.UI.Page page, string values) { page.ClientScript.RegisterStartupScript(page.GetType(), "", "<script language=javascript>alert('" + values + "')</script>"); } protected void Button1_Click(object sender, EventArgs e) { string sendStr = "#SHUTDOWN#&" + TextBox1.Text; byte[] bytes = Encoding.UTF8.GetBytes(sendStr); c.Send(bytes); } } }