您的位置:首页 > 其它

Socket一对多。。利用Socket发送命令给客户机让其执行关机命令

2010-10-22 18:00 501 查看
需求:服务器端点击“关闭”按钮,将通过Socket发送字符串"shutdown"给若干台客户机,客户机收到命令后,执行关机命令。

server端用winform【用控制台不起作用!!】,client端用控制台,其实client端也可以用winform。



服务器端代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using System.Net;
using System.Windows.Forms;

namespace server2
{
    class Class1
    {
        Socket _serverSocket;
        int _listenPortNumber;
        bool _isShutdownInProgress;
        string host = "192.168.2.2";

        public Class1()
        {
            _listenPortNumber = 2000;
            _isShutdownInProgress = false;
        }

        public void Start()
        {
            _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //_serverSocket.ExclusiveAddressUse = true;
            _serverSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

            try
            {
                _serverSocket.Bind(new IPEndPoint(/*IPAddress.Loopback*/ IPAddress.Parse(host), _listenPortNumber));
            }
            catch
            {
                _serverSocket.ExclusiveAddressUse = false;
                _serverSocket.Bind(new IPEndPoint(/*IPAddress.Loopback*/ IPAddress.Parse(host), _listenPortNumber));
            }

            _serverSocket.Listen((int)SocketOptionName.MaxConnections);
            ThreadPool.QueueUserWorkItem(new WaitCallback(onStart));
        }

        void onStart(Object unused)
        {
            // 服务器的循环, 一直监听, 来一个, 服务器一个
            // 靠的是启动客户端服务线程
            while (!_isShutdownInProgress)
            {
                try
                {
                    Socket socket = _serverSocket.Accept();// 
                    ThreadPool.QueueUserWorkItem(new WaitCallback(onSocketAccept), socket);
                }
                catch
                {
                    Thread.Sleep(100);
                }
            }
        }

        // 在程序执行过程中会有多个执行本函数的线程
        void onSocketAccept(object acceptedSocket)
        {
            if (!_isShutdownInProgress)
            {
                Socket socket = acceptedSocket as Socket;

                // 这个 socket 就是跟某个客户连接的
                string sendStr = "shutdown";
                byte[] bs = Encoding.ASCII.GetBytes(sendStr);
                socket.Send(bs, bs.Length, 0);//返回信息给客户端
                socket.Close();
            }
        }
    }
}






客户端代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;

namespace client
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                while (true)
                {
                    bool isConnect = false;
                    int port = 2000;
                    string host = "192.168.2.2";

                    ///创建终结点EndPoint
                    IPAddress ip = IPAddress.Parse(host);
                    //IPAddress ipp = new IPAddress("127.0.0.1");
                    IPEndPoint ipe = new IPEndPoint(ip, port);//把ip和端口转化为IPEndpoint实例

                    ///创建socket并连接到服务器
                    Socket c = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建Socket
                    Console.WriteLine("Conneting…");
                    

                    try
                    {
                        c.Connect(ipe);
                        isConnect = c.Poll(0, SelectMode.SelectRead);
                    }
                    catch(SocketException e)
                    {
                        if (!isConnect)
                        {
                            Console.WriteLine("未连接成功,继续连接。。。");
                            continue;
                        }
                    }

                    Console.WriteLine("连接成功,正接收数据");
                    

                    ///接受从服务器返回的信息
                    string recvStr = "";
                    byte[] recvBytes = new byte[1024];
                    int bytes = c.Receive(recvBytes, recvBytes.Length, 0);//从服务器端接受返回信息
                    recvStr += Encoding.ASCII.GetString(recvBytes, 0, bytes);
                    Console.WriteLine("client get message:{0}", recvStr);//显示服务器返回信息
                    if ("shutdown".Equals(recvStr))
                    {
                        RunDosCommand("shutdown /f /s /t 2");
                    }

                    ///一定记着用完socket后要关闭
                    c.Close();
                    break;
                }
            }
            catch (ArgumentNullException e)
            {
                Console.WriteLine("argumentNullException: {0}", e);
            }
            catch (SocketException e)
            {
                Console.WriteLine("SocketException:{0}", e);
            }
            return;
        }

        public static string RunDosCommand(string command)
        {
            Process process = new Process();
            process.StartInfo.FileName = "cmd.exe";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.RedirectStandardInput = true;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardError = true;
            process.StartInfo.CreateNoWindow = false;
            process.Start();

            process.StandardInput.WriteLine(command);
            process.StandardInput.WriteLine("exit");
            return process.StandardOutput.ReadToEnd();
        }
    }
}








使用方法:

1、修改server端和client端的ip和端口号,在onSocketAccept()方法中输入你自己想要实现的功能。

2、 调用时只要调用其Start()方法机会自动处理。Start()会自动调用onStart()方法,onStart()方法会自动调用onSocketAccept()方法,



备注:

1、服务端代码实现功能为:只要有客户端连接上服务器,那么服务器就会为其分配一个socket。

2、如果服务器端的程序没有运行,那么客户端程序会一直在控制台打印“未连接成功,继续连接。。。”。



服务器端的代码为Dobzhansky 提供,在此表示感谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐