Heim >类库下载 >C#类库 >Demonstrationscode für die C#-Socket-Server- und Client-Kommunikation

Demonstrationscode für die C#-Socket-Server- und Client-Kommunikation

大家讲道理
大家讲道理Original
2016-11-10 09:24:262885Durchsuche

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


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn