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("我在這里!!!");
            }
        }
    }
       
}