C# socket 服务端与客户端通信演示代码

清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>

C# socket 服务端与客户端通信演示代码
主要实现服务端与客户端消息和文件的相互发送,服务端可以控制客户端:重启、关机、注销,截屏(截客户端的屏)。服务端也可向客户端发送闪屏。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Runtime.InteropServices;
  
public delegate void DGShowMsg(string strMsg);
namespace Server
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            TextBox.CheckForIllegalCrossThreadCalls = false;//关闭跨线程修改控件检查
            // txtIP.Text = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0].ToString();
            txtIP.Text = Dns.GetHostByName(Dns.GetHostName()).AddressList[0].ToString();
        }
    
        [DllImport("kernel32")] ///获取系统时间
        public static extern void GetSystemTime(ref SYSTEMTIME_INFO stinfo);
          
  
        ///定义系统时间结构信息
        [StructLayout(LayoutKind.Sequential)]
        public struct SYSTEMTIME_INFO
        {
            public ushort wYear;
            public ushort wMonth;
            public ushort wDayOfWeek;
            public ushort wDay;
            public ushort wHour;
            public ushort wMinute;
            public ushort wSecond;
            public ushort wMilliseconds;
        }
  
        Socket sokWatch = null;//负责监听 客户端段 连接请求的  套接字(女生宿舍的大妈)
        Thread threadWatch = null;//负责 调用套接字, 执行 监听请求的线程
          
        //开启监听 按钮
        private void btnStartListen_Click(object sender, EventArgs e)
        {
            //实例化 套接字 (ip4寻址协议,流式传输,TCP协议)
            sokWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                  
            //创建 ip对象
            IPAddress address = IPAddress.Parse(txtIP.Text.Trim());
           // IPAddress[] addressList = Dns.GetHostEntry(Dns.GetHostName()).AddressList;
            //string ip= this.geta
            //创建网络节点对象 包含 ip和port
           // IPEndPoint endpoint = new IPEndPoint(address, int.Parse(txtPort.Text.Trim())); comboBox1.Text.Trim();
            IPEndPoint endpoint = new IPEndPoint(address, int.Parse(comboBox1.Text.Trim()));
            //将 监听套接字  绑定到 对应的IP和端口
            sokWatch.Bind(endpoint);
            //设置 监听队列 长度为10(同时能够处理 10个连接请求)
            sokWatch.Listen(20);
            threadWatch = new Thread(StartWatch);
            threadWatch.IsBackground = true;
            threadWatch.Start();
            //txtShow.AppendText("启动服务器成功......rn");
            label4.Text = "启动服务器成功......";
              
        }
        //Dictionary<string, Socket> dictSocket = new Dictionary<string, Socket>();
        Dictionary<string, ConnectionClient> dictConn = new Dictionary<string, ConnectionClient>();
  
        bool isWatch = true;
  
        #region 1.被线程调用 监听连接端口
        /// <summary>
        /// 被线程调用 监听连接端口
        /// </summary>
        void StartWatch()
        {
            string recode;
            while (isWatch)
            {
                //threadWatch.SetApartmentState(ApartmentState.STA);
                //监听 客户端 连接请求,但是,Accept会阻断当前线程
                Socket sokMsg = sokWatch.Accept();//监听到请求,立即创建负责与该客户端套接字通信的套接字
                ConnectionClient connection = new ConnectionClient(sokMsg, ShowMsg, RemoveClientConnection);
                //将负责与当前连接请求客户端 通信的套接字所在的连接通信类 对象 装入集合
                dictConn.Add(sokMsg.RemoteEndPoint.ToString(), connection);
                //将 通信套接字 加入 集合,并以通信套接字的远程IpPort作为键
                //dictSocket.Add(sokMsg.RemoteEndPoint.ToString(), sokMsg);
                //将 通信套接字的 客户端IP端口保存在下拉框里
                cboClient.Items.Add(sokMsg.RemoteEndPoint.ToString());
                MessageBox.Show("有一个客户端新添加!");
                recode = sokMsg.RemoteEndPoint.ToString();
                //调用GetSystemTime函数获取系统时间信息
                SYSTEMTIME_INFO StInfo; StInfo = new SYSTEMTIME_INFO();
                GetSystemTime(ref StInfo);
                recode +="子计算机在"+StInfo.wYear.ToString() + "年" + StInfo.wMonth.ToString() + "月" + StInfo.wDay.ToString() + "日";
                recode += (StInfo.wHour + 8).ToString() + "点" + StInfo.wMinute.ToString() + "分" + StInfo.wSecond.ToString() + "秒"+"连接服务";
                  
                //记录每台子计算机连接服务主机的日志
                StreamWriter m_sw = new StreamWriter(System.Windows.Forms.Application.StartupPath + @"\file.DAT", true);
                m_sw.WriteLine(recode);
                m_sw.WriteLine("------------------------------------------------------------------");
                m_sw.Close();
                //MessageBox.Show(recode);
                dictConn[sokMsg.RemoteEndPoint.ToString()].SendTrue();
                //启动一个新线程,负责监听该客户端发来的数据
                //Thread threadConnection = new Thread(ReciveMsg);
                //threadConnection.IsBackground = true;
                //threadConnection.Start(sokMsg);
                  
            }
        }
        #endregion
  
        //bool isRec = true;
        //与客户端通信的套接字 是否 监听消息
  
        #region 发送消息 到指定的客户端 -btnSend_Click
        //发送消息 到指定的客户端
  
        private void btnSend_Click(object sender, EventArgs e)
        {
            //byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(txtInput.Text.Trim());
            //从下拉框中 获得 要哪个客户端发送数据
            string time;
            string connectionSokKey = cboClient.Text;
            if (!string.IsNullOrEmpty(connectionSokKey))
            {
                //从字典集合中根据键获得 负责与该客户端通信的套接字,并调用send方法发送数据过去
                dictConn[connectionSokKey].Send(txtInput.Text.Trim());
                SYSTEMTIME_INFO StInfo; StInfo = new SYSTEMTIME_INFO();
                GetSystemTime(ref StInfo);
                time = StInfo.wYear.ToString() + "/" + StInfo.wMonth.ToString() + "/" + StInfo.wDay.ToString() +"  ";
                time += (StInfo.wHour + 8).ToString() + ":" + StInfo.wMinute.ToString();
                richTextBox1.AppendText(time + "rn");
                richTextBox1.AppendText("对" + cboClient.Text +"说:"+ txtInput.Text.Trim() + "rn");
                txtInput.Text = "";
                //sokMsg.Send(arrMsg);
            }
            else
            {
                MessageBox.Show("请选择要发送的子计算机~~");
            }
        }
        #endregion
  
        //发送闪屏
        private void btnShack_Click(object sender, EventArgs e)
        {
            string connectionSokKey = cboClient.Text;
            if (!string.IsNullOrEmpty(connectionSokKey))
            {
                dictConn[connectionSokKey].SendShake();
            }
            else
            {
                MessageBox.Show("请选择要发送的子计算机~~");
            }
        }
        //群闪
        private void btnShackAll_Click(object sender, EventArgs e)
        {
            foreach (ConnectionClient conn in dictConn.Values)
            {
                conn.SendShake();
            }
        }
         
        #region 2 移除与指定客户端的连接 +void RemoveClientConnection(string key)
        /// <summary>
        /// 移除与指定客户端的连接
        /// </summary>
        /// <param name="key">指定客户端的IP和端口</param>
        public void RemoveClientConnection(string key)
        {
            if (dictConn.ContainsKey(key))
            {
                dictConn.Remove(key);
                MessageBox.Show(key +"断开连接");
                cboClient.Items.Remove(key);
            }
        }
        #endregion
  
        //选择要发送的文件
        private void btnChooseFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                txtFilePath.Text = ofd.FileName;
            }
        }
  
        //发送文件
        private void btnSendFile_Click(object sender, EventArgs e)
        {
            //拿到下拉框中选中的客户端IPPORT
            string key = cboClient.Text;
            if (!string.IsNullOrEmpty(key))
            {
                dictConn[key].SendFile(txtFilePath.Text.Trim());
               // txtFilePath.Text = "";
            }
            else
            {
                MessageBox.Show("请选择要发送的子计算机~");
            }
        }
  
        #region 向文本框显示消息 -void ShowMsg(string msgStr)
        /// <summary>
        /// 向文本框显示消息
        /// </summary>
        /// <param name="msgStr">消息</param>
        public void ShowMsg(string msgStr)
        {
            //MessageBox.Show("1040414");
            txtShow1.AppendText(msgStr + "rn");
        }
        #endregion
//群消息
        private void btnSendMsgAll_Click(object sender, EventArgs e)
        {
            string time;
            foreach (ConnectionClient conn in dictConn.Values)
            {
                conn.Send(txtInput.Text.Trim());
                  
            }
            SYSTEMTIME_INFO StInfo; StInfo = new SYSTEMTIME_INFO();
            GetSystemTime(ref StInfo);
            time = StInfo.wYear.ToString() + "/" + StInfo.wMonth.ToString() + "/" + StInfo.wDay.ToString()  + "  ";
            time += (StInfo.wHour + 8).ToString() + ":" + StInfo.wMinute.ToString();
            richTextBox1.AppendText(time + "rn");
            richTextBox1.AppendText("群发消息:"+ txtInput.Text.Trim() + "rn");
            txtInput.Text = "";
        }
//群发文件
        private void button1_Click(object sender, EventArgs e)
        {
  
            foreach (ConnectionClient conn in dictConn.Values)
            {
               // dictConn.SendFile(txtFilePath.Text.Trim());
                conn.SendFile(txtFilePath.Text.Trim());
                  
  
            }
        }
  
        private void button2_Click(object sender, EventArgs e)
        {
            string connectionSokKey = cboClient.Text;
            if (!string.IsNullOrEmpty(connectionSokKey))
            {
                dictConn[connectionSokKey].guanji();
            }
            else
            {
                MessageBox.Show("请选择要发送的子计算机~~");
            }
        }
  
        private void button3_Click(object sender, EventArgs e)
        {
            string connectionSokKey = cboClient.Text;
            if (!string.IsNullOrEmpty(connectionSokKey))
            {
                dictConn[connectionSokKey].chongqi();
            }
            else
            {
                MessageBox.Show("请选择要发送的子计算机~~");
            }
        }
  
        private void button4_Click(object sender, EventArgs e)
        {
            string connectionSokKey = cboClient.Text;
            if (!string.IsNullOrEmpty(connectionSokKey))
            {
                dictConn[connectionSokKey].zhuxiao();
            }
            else
            {
                MessageBox.Show("请选择要发送的子计算机~~");
            }
        }
  
        private void button5_Click(object sender, EventArgs e)
        {
            string connectionSokKey = cboClient.Text;
            if (!string.IsNullOrEmpty(connectionSokKey))
            {
                dictConn[connectionSokKey].jieping();
            }
            else
            {
                MessageBox.Show("请选择要发送的子计算机~~");
            }
        }
  
         
  
    }
    ///////////////////////////////////////////////////////////////////////////////////////
   ////////////////////////////////////////////////////////////////////////////////////////
   ////在这里,我新建了一个与客户端的通信和线程的类(ConnectionClient)//////////////////////
    /// <summary>
    /// 与客户端的 连接通信类(包含了一个 与客户端 通信的 套接字,和线程)
    /// </summary>
   public class ConnectionClient
    {
        Socket sokMsg;
        DGShowMsg dgShowMsg;//负责 向主窗体文本框显示消息的方法委托
        DGShowMsg dgRemoveConnection;// 负责 从主窗体 中移除 当前连接
        Thread threadMsg;
  
        #region 构造函数
        /// <summary>
        ///
        /// </summary>
        /// <param name="sokMsg">通信套接字</param>
        /// <param name="dgShowMsg">向主窗体文本框显示消息的方法委托</param>
        public ConnectionClient(Socket sokMsg, DGShowMsg dgShowMsg, DGShowMsg dgRemoveConnection)
        {
            this.sokMsg = sokMsg;
            this.dgShowMsg = dgShowMsg;
            this.dgRemoveConnection = dgRemoveConnection;
  
            this.threadMsg = new Thread(RecMsg);
            this.threadMsg.IsBackground = true;
            this.threadMsg.Start();
        }
        #endregion
  
        bool isRec = true;
        #region 02负责监听客户端发送来的消息
        void RecMsg()
        {
            while (isRec)
            {
                try
                {
                    byte[] arrMsg = new byte[1024 * 1024 * 1];
                    //接收 对应 客户端发来的消息
                    int length = sokMsg.Receive(arrMsg);
                    // string abc = Encoding.Default.GetString(arrMsg);
                    // MessageBox.Show(abc);
                    //将接收到的消息数组里真实消息转成字符串                                       
                    if (arrMsg[0] == 1)
                    {
                         //string abc = Encoding.Default.GetString(arrMsg);
                         //MessageBox.Show(abc);
                         //发送来的是文件
                         //MessageBox.Show("00000s");
                         //SaveFileDialog sfd = new SaveFileDialog();
                         SaveFileDialog sfd = new SaveFileDialog();
                         sfd.Filter = "文本文件(.txt)|*.txt|所有文件(*.*)|*.*";
                         // MessageBox.Show(sfd.Filter);
                          
                         //sfd.ShowDialog();
                         //弹出文件保存选择框
                         if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                         {
                             //MessageBox.Show("111110");
                             //创建文件流
                             using (FileStream fs = new FileStream(sfd.FileName, FileMode.OpenOrCreate))
                             {
                                 fs.Write(arrMsg, 1, length - 1);
                                 MessageBox.Show("文件保存成功!");
                             }
                         }
                     }
                    /*else if(arrMsg[0] == 2)
                    {
                          
                        //  MemoryStream ms = new MemoryStream(arrMsg, 0, length-1);
                        MemoryStream ms = new MemoryStream(arrMsg);
                        Image returnImage = Image.FromStream(ms);//??????????
                        PictureBox district = (PictureBox)Application.OpenForms["Form1"].Controls["pictureBox1"].Controls["pictureBox1"];
                        district.Image  =  returnImage;
                       // this.saveFileDialog1.FileName = "";//清空名称栏
                       
                        /* 
                         SaveFileDialog sfd = new SaveFileDialog();
                        sfd.Filter = "图像文件(.jpg)|*.jpg|所有文件(*.*)|*.*";
                        MessageBox.Show(sfd.Filter);
                        if (DialogResult.OK == sfd.ShowDialog())
                        {
                            string strFileName = sfd.FileName;
                            //Image img = (Image)this.pictureBox1.Image;
                            returnImage.Save(strFileName);
                        }
                         
                    }*/
                     else//发送来的是消息
                     {
                        //MessageBox.Show("2222");
                        string strMsg = sokMsg.RemoteEndPoint.ToString()+"说:"+"rn"+System.Text.Encoding.UTF8.GetString(arrMsg, 0, length); //// 我在这里  Request.ServerVariables.Get("Remote_Addr").ToString()+
                        //通过委托 显示消息到 窗体的文本框
                        dgShowMsg(strMsg);
                      }
                       
                          
                      
                     //MessageBox.Show("11111");
              }
              catch (Exception ex)
               {
                  isRec = false;
                 //从主窗体中 移除 下拉框中对应的客户端选择项,同时 移除 集合中对应的 ConnectionClient对象
                    dgRemoveConnection(sokMsg.RemoteEndPoint.ToString());
                }
            }
        }
        #endregion
  
        #region 03向客户端发送消息
        /// <summary>
        /// 向客户端发送消息
        /// </summary>
        /// <param name="strMsg"></param>
        public void Send(string strMsg)
        {
            byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);
            byte[] arrMsgFinal = new byte[arrMsg.Length + 1];
  
            arrMsgFinal[0] = 0;//设置 数据标识位等于0,代表 发送的是 文字
            arrMsg.CopyTo(arrMsgFinal, 1);
  
            sokMsg.Send(arrMsgFinal);
        }
        #endregion
  
        #region 04向客户端发送文件数据 +void SendFile(string strPath)
        /// <summary>
        /// 04向客户端发送文件数据
        /// </summary>
        /// <param name="strPath">文件路径</param>
        public void SendFile(string strPath)
        {
            //通过文件流 读取文件内容
            //MessageBox.Show("12540");
            using (FileStream fs = new FileStream(strPath, FileMode.OpenOrCreate))
            {
                byte[] arrFile = new byte[1024 * 1024 * 2];
                //读取文件内容到字节数组,并 获得 实际文件大小
                int length = fs.Read(arrFile, 0, arrFile.Length);
                //定义一个 新数组,长度为文件实际长度 +1
                byte[] arrFileFina = new byte[length + 1];
                arrFileFina[0] = 1;//设置 数据标识位等于1,代表 发送的是文件
                //将 文件数据数组 复制到 新数组中,下标从1开始
                //arrFile.CopyTo(arrFileFina, 1);
                Buffer.BlockCopy(arrFile, 0, arrFileFina, 1, length);
               // MessageBox.Show("120");
                //发送文件数据
                sokMsg.Send(arrFileFina);//, 0, length + 1, SocketFlags.None);
            }
        }
        #endregion
  
        #region 05向客户端发送闪屏
        /// <summary>
        /// 向客户端发送闪屏
        /// </summary>
        /// <param name="strMsg"></param>
        public void SendShake()
        {
            byte[] arrMsgFinal = new byte[1];
            arrMsgFinal[0] = 2;
            sokMsg.Send(arrMsgFinal);
        }
        #endregion
  
        #region 06关闭与客户端连接
        /// <summary>
        /// 关闭与客户端连接
        /// </summary>
        public void CloseConnection()
        {
            isRec = false;
        }
        #endregion
  
        #region 07向客户端发送连接成功提示
        /// <summary>
        /// 向客户端发送连接成功提示
        /// </summary>
        /// <param name="strMsg"></param>
        public void SendTrue()
        {
            byte[] arrMsgFinal = new byte[1];
            arrMsgFinal[0] = 3;
            sokMsg.Send(arrMsgFinal);
        }
        #endregion
  
        #region 08向客户端发送关机命令
        /// <summary>
        /// 向客户端发送关机命令
        /// </summary>
        /// <param name="strMsg"></param>
        public void guanji()
        {
            byte[] arrMsgFinal = new byte[1];
            arrMsgFinal[0] = 4;
            sokMsg.Send(arrMsgFinal);
        }
        #endregion
  
        #region 09向客户端发送重启命令
        /// <summary>
        /// 向客户端发送关机命令
        /// </summary>
        /// <param name="strMsg"></param>
        public void chongqi()
        {
            byte[] arrMsgFinal = new byte[1];
            arrMsgFinal[0] = 5;
            sokMsg.Send(arrMsgFinal);
        }
        #endregion
  
        #region 10向客户端发送待机命令
        /// <summary>
        /// 向客户端发送关机命令
        /// </summary>
        /// <param name="strMsg"></param>
        public void zhuxiao()
        {
            byte[] arrMsgFinal = new byte[1];
            arrMsgFinal[0] = 6;
            sokMsg.Send(arrMsgFinal);
        }
       #endregion
  
        #region 11向客户端发送截屏命令
        /// <summary>
        /// 向客户端发送截屏命令
        /// </summary>
        /// <param name="strMsg"></param>
        public void jieping()
        {
            byte[] arrMsgFinal = new byte[1];
            arrMsgFinal[0] = 7;
            sokMsg.Send(arrMsgFinal);
        }
        #endregion
    }
  
}

客户端:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Windows.Forms;
using System.IO;
using System.Text;
using System.Runtime.InteropServices;
  
  
public delegate void DGShowMsg(string strMsg);
namespace Client
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            TextBox.CheckForIllegalCrossThreadCalls = false;
              
        }
        #region[成员函数]
        ///<summary>
        ///图像函数
        ///</summary>
        private Image _img;
        #endregion
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
  
        internal struct TokPriv1Luid
        {
  
            public int Count;
  
            public long Luid;
  
            public int Attr;
  
        }
  
        [DllImport("kernel32.dll", ExactSpelling = true)]
  
        internal static extern IntPtr GetCurrentProcess();
  
        [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
  
        internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);
  
        [DllImport("advapi32.dll", SetLastError = true)]
  
        internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
  
        [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
  
        internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
  
        ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
  
        [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
  
        internal static extern bool ExitWindowsEx(int flg, int rea);
  
        internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
  
        internal const int TOKEN_QUERY = 0x00000008;
  
        internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
  
        internal const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
  
        internal const int EWX_LOGOFF = 0x00000000;  //注销
  
        internal const int EWX_SHUTDOWN = 0x00000001;   //关机
  
        internal const int EWX_REBOOT = 0x00000002;     //重启
  
        internal const int EWX_FORCE = 0x00000004;
  
        internal const int EWX_POWEROFF = 0x00000008;    //断开电源
  
        internal const int EWX_FORCEIFHUNG = 0x00000010;  //强制终止未响应的程序
  
       // internal const int WM_POWERBROADCAST
        
  
  
        private static void DoExitWin(int flg)
        {
  
            bool ok;
  
            TokPriv1Luid tp;
  
            IntPtr hproc = GetCurrentProcess();
  
            IntPtr htok = IntPtr.Zero;
  
            ok = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
  
            tp.Count = 1;
  
            tp.Luid = 0;
  
            tp.Attr = SE_PRIVILEGE_ENABLED;
  
            ok = LookupPrivilegeValue(null, SE_SHUTDOWN_NAME, ref tp.Luid);
  
            ok = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
  
            ok = ExitWindowsEx(flg, 0);
  
        }
  
  
        Socket sokClient = null;//负责与服务端通信的套接字
        Thread threadClient = null;//负责 监听 服务端发送来的消息的线程
        bool isRec = true; //是否循环接收服务端数据
       // Dictionary<string, ConnectionClient> dictConn = new Dictionary<string, ConnectionClient>();
        private void btnConnect_Click(object sender, EventArgs e)
        {
            //实例化 套接字
            sokClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //创建 ip对象
            IPAddress address = IPAddress.Parse(txtIP.Text.Trim());
            //MessageBox.Show("address");
            //创建网络节点对象 包含 ip和port
            IPEndPoint endpoint = new IPEndPoint(address, int.Parse(comboBox1.Text.Trim()));
            //连接 服务端监听套接字
            sokClient.Connect(endpoint);
  
            //创建负责接收 服务端发送来数据的 线程
            threadClient = new Thread(ReceiveMsg);
            threadClient.IsBackground = true;
            //如果在win7下要通过 某个线程 来调用 文件选择框的代码,就需要设置如下
            threadClient.SetApartmentState(ApartmentState.STA);
            threadClient.Start();
        }
         
  
        /// <summary>
        /// 接收服务端发送来的消息数据
        /// </summary>
        void ReceiveMsg()
        {
            while (isRec)
            {
                byte[] msgArr = new byte[1024 * 1024 * 1];//接收到的消息的缓冲区
                int length = 0;
                //接收服务端发送来的消息数据
                length = sokClient.Receive(msgArr);//Receive会阻断线程
                if (msgArr[0] == 0)//发送来的是文字
                {
                    string strMsg = System.Text.Encoding.UTF8.GetString(msgArr, 1, length - 1);
                    txtShow.AppendText(strMsg + "rn");
                }
                else if (msgArr[0] == 1)
                {
                    //发送来的是文件
                    //string abc = Encoding.Default.GetString(msgArr);
                    //MessageBox.Show(abc);
                    SaveFileDialog sfd = new SaveFileDialog();
                    sfd.Filter = "文本文件(.txt)|*.txt|所有文件(*.*)|*.*";
                    //弹出文件保存选择框
                    if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    {
                        //创建文件流
                        using (FileStream fs = new FileStream(sfd.FileName, FileMode.OpenOrCreate))
                        {
                            fs.Write(msgArr, 1, length - 1);
                            MessageBox.Show("文件保存成功!");
                        }
                    }
                }
                else if (msgArr[0] == 2)
                {
                    ShakeWindow();
                }
                else if (msgArr[0] == 3)
                {
                    MessageBox.Show("连接成功");
                }
                else if (msgArr[0] == 4)
                {
                    DoExitWin(EWX_SHUTDOWN); 
                }
                else if (msgArr[0] == 5)
                {
                    DoExitWin(EWX_REBOOT);
                }
                else if (msgArr[0] == 6)
                {
                    DoExitWin(EWX_LOGOFF);
                }
                else if (msgArr[0] == 7)
                {
                     
                    PrintScreen();
                }
  
            }
        }
  
        #region[方法]
        ///<summary>
        ///截屏
        ///</summary>
        private void PrintScreen()
        {
             
            string Opath = @"C:/Picture";
            if (Opath.Substring(Opath.Length - 1, 1) != @"/")
               Opath = Opath + @"/";
            string photoname = DateTime.Now.Ticks.ToString();
            string path1 = Opath + DateTime.Now.ToShortDateString();
            if (!Directory.Exists(path1))
                Directory.CreateDirectory(path1);
            try
            {
             
                Screen scr = Screen.PrimaryScreen;
                Rectangle rc = scr.Bounds;
                int iWidth = rc.Width;
                int iHeight = rc.Height;
                Bitmap myImage = new Bitmap(iWidth, iHeight);
                Graphics gl = Graphics.FromImage(myImage);
                gl.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(iWidth, iHeight));
                _img = myImage;
                //pictureBox1.Image = _img;
                // IntPtr dc1 = gl.GetHdc();
                //gl.ReleaseHdc(dc1);
                MessageBox.Show(path1);
                MessageBox.Show(photoname);
                _img.Save(path1 + "//" + photoname + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg); 
               // _img.Save("D:\1.jpeg");
                SendFile(path1+"//"+photoname+".jpg");
            }
            catch (Exception ex)
            {
                MessageBox.Show("截屏失败!n" + ex.Message.ToString() + "n" + ex.StackTrace.ToString());
            }
              
           // MessageBox.Show("12322222");
            /////////////////////////////////////////////////////////
            ///////////////////发送图片流///////////////////////////
           /*
            MemoryStream ms = new MemoryStream();
            byte[] imagedata = null;
            _img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
            imagedata = ms.GetBuffer();
  
            byte[] arrFile = new byte[1024 * 1024 * 2];
            //读取文件内容到字节数组,并 获得 实际文件大小
            int length = ms.Read(arrFile, 0, arrFile.Length);
            // int length = ms.Read(arrFile, 0, arrFile.Length);
            //定义一个 新数组,长度为文件实际长度 +1
            byte[] arrFileFina = new byte[length + 1];
            arrFileFina[0] = 2;//设置 数据标识位等于1,代表 发送的是文件
            //将 图片流数据数组 复制到 新数组中,下标从1开始
            //arrFile.CopyTo(arrFileFina, 1);
            Buffer.BlockCopy(arrFile, 0, arrFileFina, 1, length);
            //发送文件数据 
            sokClient.Send(arrFileFina);//, 0, length + 1, SocketFlags.None);
            //MessageBox.Show("我在这里!!!");
            // byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(_img);
            MessageBox.Show("2222");
            */
        }
        #endregion
/*
        private void button1_Click(object sender, EventArgs e)
        {
            // this.WindowState = FormWindowState.Minimized;
            PrintScreen();
            if (_img != null)
            {
                this.pictureBox1.Image = _img;
            }
            this.WindowState = FormWindowState.Normal;
        }
*/
        /// <summary>
        /// 闪屏
        /// </summary>
        private void ShakeWindow()
        {
            Random ran = new Random();
            //保存 窗体原坐标
            System.Drawing.Point point = this.Location;
            for (int i = 0; i < 30; i++)
            {
                //随机 坐标
                this.Location = new System.Drawing.Point(point.X + ran.Next(8), point.Y + ran.Next(8));
                System.Threading.Thread.Sleep(15);//休息15毫秒
                this.Location = point;//还原 原坐标(窗体回到原坐标)
                System.Threading.Thread.Sleep(15);//休息15毫秒
            }
        }
        //发送消息
        private void btnSend_Click(object sender, EventArgs e)
        {
            byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(txtInput.Text.Trim());
            sokClient.Send(arrMsg);
            richTextBox1.AppendText(txtInput.Text.Trim()+"rn");
            txtInput.Text = "";
        }
  
        private void btnChooseFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                txtFilePath.Text = ofd.FileName;
            }
        }
        //发送文件
        private void btnSendFile_Click(object sender, EventArgs e)
        {
            string key = txtIP.Text + ":" + comboBox1.Text.Trim();
            //MessageBox.Show(key);
            if (!string.IsNullOrEmpty(key))
            {
                SendFile(txtFilePath.Text.Trim());
               // MessageBox.Show("1230");
                // txtFilePath.Text = "";
            }
        }
        private void SendFile(string strPath)
        {
            //通过文件流 读取文件内容
             
            using (FileStream fs = new FileStream(strPath, FileMode.OpenOrCreate))
            {
                byte[] arrFile = new byte[1024 * 1024 * 2];
                //读取文件内容到字节数组,并 获得 实际文件大小
                int length = fs.Read(arrFile, 0, arrFile.Length);
                //定义一个 新数组,长度为文件实际长度 +1
                byte[] arrFileFina = new byte[length + 1];
                arrFileFina[0] = 1;//设置 数据标识位等于1,代表 发送的是文件
                //将 文件数据数组 复制到 新数组中,下标从1开始
                //arrFile.CopyTo(arrFileFina, 1);
                Buffer.BlockCopy(arrFile, 0, arrFileFina, 1, length);
                //发送文件数据 
                sokClient.Send(arrFileFina);//, 0, length + 1, SocketFlags.None);
                //MessageBox.Show("我在这里!!!");
            }
        }
    }
       
}