C#简单远程控制制作源代码程序以及思路(服务器端)

48 篇文章 1 订阅

远程控制无非就是在有网络的情况下发送一些操作指令到客户机上,

其实看软件的范围是用来干什么的,网络游戏都可以定义为远程控制软件,

之前不是说腾讯经常扫描别人的硬盘。

所以这里使用socket来简单讲一下做远程控制软件的原理。

服务器端监听一个IP和端口,会用socket的应该都知道。

首先就是建立一个socket服务器,不多说贴代码。

  1.   
  1. public SocketAdmin(string _ip,out Socket _socket, int _port, out Dictionary<string, Socket> _dicSocket)//这是一个构造方法。用来绑定ip和端口并且返回数据   
  2.         {  
  3.             ip = _ip;  
  4.             port = _port;  
  5.             ServerRun();  
  6.             _socket=socket ;  
  7.             _dicSocket=dicOnlineSocket ;  
  8.   
  9.         }  
  10.         private static string ip;  
  11.         private static int port;  
  12.         private static Socket socket;  
  13.         private static void ServerRun()//开始socket服务   
  14.         {  
  15.             socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);  
  16.             IPEndPoint _ipport = new IPEndPoint(IPAddress.Parse(ip), port);  
  17.             socket.Bind(_ipport);  
  18.             socket.Listen(50);  
  19.             Thread _thread = new Thread(WatchAccpt);//使用一个线程来监听与服务器连接上的客户端   
  20.             _thread.IsBackground = true;  
  21.             _thread.Start();  
  22.         }  
  23.         /// <summary>   
  24.         /// 所有活动的socket连接   
  25.         /// </summary>   
  26.         public static Dictionary<string, Socket> dicOnlineSocket = new Dictionary<string, Socket>();  
  27.         /// <summary>   
  28.         /// 用来监听用户的信息   
  29.         /// </summary>   
  30.         private static void WatchAccpt()  
  31.         {  
  32.             while (socket != null)  
  33.             {  
  34.                 Socket _acpSocket = socket.Accept();  
  35.                 Console.WriteLine("连接:" + _acpSocket.RemoteEndPoint.ToString());  
  36.                 if (!dicOnlineSocket.ContainsKey(_acpSocket.RemoteEndPoint.ToString()))//如果有新的用户连接上时就会添加到字典中   
  37.                     dicOnlineSocket.Add(_acpSocket.RemoteEndPoint.ToString(), _acpSocket);  
  38.             }  
  39.         }  
  1.   
这个方法是自己封装的一个socket 操作类。

如果要使用直接使用下面这句代码:

SocketAdmin socketAdmin = new SocketAdmin("192.168.0.200",out _socket, 6160, out dicOnline);

由于有2个参数是要传出来的,所以还要先定义2个变量

private Socket _socket;private static Dictionary<string, Socket> dicOnline;

这是服务器的管理界面

[csharp] view plain copy print ?
  1. private void btnStart_Click(object sender, EventArgs e)  
  2.         {  
  3.             SocketAdmin socketAdmin = new SocketAdmin("192.168.0.200",out _socket, 6160, out dicOnline);  
  4.             Thread thread = new Thread(AddLstOnline);  
  5.             thread.IsBackground = true;  
  6.             thread.Start();  
  7.   
  8.             thread = new Thread(LoopInfoMsg);//循环发送消息的方法   
  9.             thread.IsBackground = true;  
  10.             thread.Start();  
  11.         }  

在按下监听按钮的时候会启动2个线程。

一个用来在listbox中显示在线人数,代码如下:

  1. /// <summary>   
  2.         /// 加入在线人数   
  3.         /// </summary>   
  4.         private void AddLstOnline()  
  5.         {  
  6.             while (true)  
  7.             {  
  8.                 if (lstOnline.Items.Count != dicOnline.Count)//说明有新的用户连上   
  9.                 {  
  10.                     lstOnline.Items.Clear();  
  11.                     foreach (var item in dicOnline.Keys)  
  12.                     {  
  13.                         lstOnline.Items.Add(item);  
  14.                     }  
  15.                 }  
  16.             }  
  17.         }  
/// <summary>
        /// 加入在线人数
        /// </summary>
        private void AddLstOnline()
        {
            while (true)
            {
                if (lstOnline.Items.Count != dicOnline.Count)//说明有新的用户连上
                {
                    lstOnline.Items.Clear();
                    foreach (var item in dicOnline.Keys)
                    {
                        lstOnline.Items.Add(item);
                    }
                }
            }
        }
另一个线程用来发送向客户端发送消息的,也是经过封装的方法,代码有点复杂,如下:

  1. /// <summary>   
  2. /// 发用户的信息,只发个用户本人的   
  3. /// </summary>   
  4. /// <param name="type1"></param>   
  5. /// <param name="type2"></param>   
  6. /// <param name="msg"></param>   
  7. public void Put_SendInfoToPool(string key, string data,Socket sendSocket)  
  8. {  
  9.     if (PoolInfoMsg == null)  
  10.     {  
  11.         PoolInfoMsg = new ArrayList();  
  12.     }  
  13.     _tempSocket = sendSocket;  
  14.     MSGStruct msg = new MSGStruct();  
  15.     msg.key = key;  
  16.     msg.json = data;  
  17.     string json = JsonMapper.ToJson(msg);  
  18.     byte[] byteArr = System.Text.Encoding.UTF8.GetBytes(json);  
  19.     PoolInfoMsg.Add(byteArr);  
  20. }  
  21. private Socket _tempSocket;  
  22. private ArrayList PoolInfoMsg;  
  23. public void LoopInfoMsg()  
  24. {  
  25.     while (_socket != null)  
  26.     {  
  27.         if (PoolInfoMsg != null && PoolInfoMsg.Count > 0)//表示有消息   
  28.         {  
  29.             _tempSocket.Send((byte[])PoolInfoMsg[0]);  
  30.   
  31.             PoolInfoMsg.RemoveAt(0);//移除已发的消息   
  32.         }  
  33.         Thread.Sleep(20);  
  34.   
  35.     }  
  36. }  
        /// <summary>
        /// 发用户的信息,只发个用户本人的
        /// </summary>
        /// <param name="type1"></param>
        /// <param name="type2"></param>
        /// <param name="msg"></param>
        public void Put_SendInfoToPool(string key, string data,Socket sendSocket)
        {
            if (PoolInfoMsg == null)
            {
                PoolInfoMsg = new ArrayList();
            }
            _tempSocket = sendSocket;
            MSGStruct msg = new MSGStruct();
            msg.key = key;
            msg.json = data;
            string json = JsonMapper.ToJson(msg);
            byte[] byteArr = System.Text.Encoding.UTF8.GetBytes(json);
            PoolInfoMsg.Add(byteArr);
        }
        private Socket _tempSocket;
        private ArrayList PoolInfoMsg;
        public void LoopInfoMsg()
        {
            while (_socket != null)
            {
                if (PoolInfoMsg != null && PoolInfoMsg.Count > 0)//表示有消息
                {
                    _tempSocket.Send((byte[])PoolInfoMsg[0]);

                    PoolInfoMsg.RemoveAt(0);//移除已发的消息
                }
                Thread.Sleep(20);

            }
        }

这里发送消息使用的是json发送字符串。

  1. /// <summary>   
  2.         /// 消息类 键是id,data是json字符串   
  3.         /// </summary>   
  4.         public class MSGStruct  
  5.         {  
  6.             public string key;  
  7.             public string json;  
  8.         }  
/// <summary>
        /// 消息类 键是id,data是json字符串
        /// </summary>
        public class MSGStruct
        {
            public string key;
            public string json;
        }

消息会有一个类,定义建和发送的值。
下面看发送消息按钮的实现代码:

  1. private void btnSendMsg_Click(object sender, EventArgs e)  
  2.         {  
  3.             if (lstOnline.SelectedItem!=null)//如果已经选中了就准备发消息   
  4.                 Put_SendInfoToPool("text", txtString.Text, dicOnline[lstOnline.SelectedItem.ToString()]);  
  5.             else  
  6.                 MessageBox.Show("请选择接受对象");  
  7.         }  
private void btnSendMsg_Click(object sender, EventArgs e)
        {
            if (lstOnline.SelectedItem!=null)//如果已经选中了就准备发消息
                Put_SendInfoToPool("text", txtString.Text, dicOnline[lstOnline.SelectedItem.ToString()]);
            else
                MessageBox.Show("请选择接受对象");
        }
是不是经过封装以后就很简单了。这样就可以把消息发送到客户端了。


另一个简单的功能就是让客户端代码来不定期的打开网页。

首先要定义一个Json对象用来发送消息。

  1. public class OpenClass  
  2. {  
  3.     /// <summary>   
  4.     /// 要打开的网站   
  5.     /// </summary>   
  6.     public string openUrl;  
  7.     /// <summary>   
  8.     /// 间隔的时间   
  9.     /// </summary>   
  10.     public string stopTime;  
  11.     /// <summary>   
  12.     /// 是否开始,1表示开始,0表示关闭   
  13.     /// </summary>   
  14.     public int IsStart;  
  15. }  
        public class OpenClass
        {
            /// <summary>
            /// 要打开的网站
            /// </summary>
            public string openUrl;
            /// <summary>
            /// 间隔的时间
            /// </summary>
            public string stopTime;
            /// <summary>
            /// 是否开始,1表示开始,0表示关闭
            /// </summary>
            public int IsStart;
        }

然后用一个方法来给他赋值

  1. private void SendOpenUrl(string url,string time,int start)  
  2.         {  
  3.             OpenClass open = new OpenClass();  
  4.             open.openUrl = url;  
  5.             open.stopTime = time;  
  6.             open.IsStart = start;  
  7.             string josn=JsonMapper.ToJson(open);  
  8.             if (lstOnline.SelectedItem != null)//如果已经选中了就准备发消息   
  9.                 Put_SendInfoToPool("openUrl", josn, dicOnline[lstOnline.SelectedItem.ToString()]);  
  10.             else  
  11.                 MessageBox.Show("请选择接受对象");  
  12.         }  
private void SendOpenUrl(string url,string time,int start)
        {
            OpenClass open = new OpenClass();
            open.openUrl = url;
            open.stopTime = time;
            open.IsStart = start;
            string josn=JsonMapper.ToJson(open);
            if (lstOnline.SelectedItem != null)//如果已经选中了就准备发消息
                Put_SendInfoToPool("openUrl", josn, dicOnline[lstOnline.SelectedItem.ToString()]);
            else
                MessageBox.Show("请选择接受对象");
        }

好写好2个方法以后,要发消息到客户端,就是实现开始和停止2个按钮的功能。

首先是开始按钮的代码:

  1. private void btnOpenStart_Click(object sender, EventArgs e)  
  2.         {  
  3.             SendOpenUrl(txtUrl.Text,txtTime.Text, 1);  
  4.         }  
private void btnOpenStart_Click(object sender, EventArgs e)
        {
            SendOpenUrl(txtUrl.Text,txtTime.Text, 1);
        }
然后是停止按钮的代码

  1. private void btnOpenStop_Click(object sender, EventArgs e)  
  2. {  
  3.     SendOpenUrl(txtUrl.Text, txtTime.Text, 0);  
  4. }  
        private void btnOpenStop_Click(object sender, EventArgs e)
        {
            SendOpenUrl(txtUrl.Text, txtTime.Text, 0);
        }

一些规则已经定义好以后操作起来就非常简单了。

服务器就简单实现了2个功能,如果需要什么其他的功能只需要定义好一个消息结构,然后在写实现的方法,整个模块已经可以完成了。


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值