安之老大爷 2017-08-11 02:05 采纳率: 0%
浏览 878

【新手求教】关于C#循环无法跳出问题,代码片段如下

最近遇到了个问题,主要是在做一个异步通讯的时候会一直循环在某个代码段,始终无法跳出,还望各位大神给个建议

  • 写回答

8条回答 默认 最新

  • 安之老大爷 2017-08-11 02:06
    关注
    
    

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net;
    using System.Threading;
    using System.Net.Sockets;
    using RetDLL;
    using System.Collections; //在C#中使用ArrayList必须引用Collections类
    using System.Diagnostics;

    namespace PTVKey
    {
    class ThreadServer:Form1
    {
    private byte[] recvBuffer;//存放消息数据
    private Socket socket;//为客户端建立的SOCKET连接
    public Form1 form1;
    private bool bStop;
    private bool bResult;
    public int indexStra;
    public string getkeymsg;
    private Thread thread;
    public string cmd ="00#0";
    private KeyInfo keyInfo;

        public ThreadServer()
        {
    
        }
    
        public ThreadServer(Socket s, Form1 frm)
        {
            this.form1 = frm;
            this.socket = s;
            recvBuffer = new byte[65535];
            bStop = false;
            bResult = false;
        }
    
         public void End()
        {
            bStop = true;
        }
    
        public void Start()
        {
            socket.BeginReceive(recvBuffer, 0, recvBuffer.Length, 0, new AsyncCallback(RecieveCallBack), socket);
            Thread.Sleep(50);
    
            SendKey();
            //开始心跳线程
            thread = new Thread(Run);
            thread.Start();   
        }
    
        private Ret SendKey()
        {
            Ret ret = new Ret(true);
    
            keyInfo = new KeyInfo();
            ret = GetKeyFromDB(ref keyInfo);
            if (!ret.b)
            {
                return ret;
            }
            //SET#KEY#160#字符串
            string key = keyInfo.mainKey.Trim() ;
            string msg = "SET#KEY#" + key.Length.ToString() + "#" + keyInfo.mainKey;
            ret = sendServerMsg(msg);
    
            return ret; 
        }
    
    
        #region 功能函数
    
        /// <summary>
        /// 从数据库中获取一条未使用的KEY
        /// </summary>
        /// <returns></returns>
        private Ret GetKeyFromDB(ref KeyInfo keyInfo)
        {
            Ret ret = new Ret(true);
    
            DBData dd = new DBData();
            string strSQL = string.Format("select top 1 * from key_info where batchId= {0} and status = 0 order by createTime asc" , Program.batchInfo.id);
    
            ArrayList list = new ArrayList();
            int cnt = dd.getKeInfo(strSQL, ref list);
            if (cnt <= 0)
            {
                ret.b = false;
                return ret;
            }
            keyInfo = (KeyInfo)list[0];
    
            return ret; 
        }
    
        /// <summary>
        /// 修改数据库中key使用状态
        /// </summary>
        /// <returns></returns>
        private Ret ModifyKeyStatus()
        {
            Ret ret = new Ret(true);
    
            string strSQL = string.Format("update  key_info set status = 1 where batchId= {0} and id = {1}", Program.batchInfo.id , keyInfo.id);
            DB db = new DB();
            int res = db.executeSQLNonQuery(strSQL);
            if (res <= 0)
            {
                ret.b = false;
            }
            return ret; 
        }
        #endregion 
    
    
        static bool IsSocketConnected(Socket s)
        {
            return !((s.Poll(1000, SelectMode.SelectRead) && (s.Available == 0)) || !s.Connected);
        }
    
    
        private  void Run()
        {
            string strip = socket.RemoteEndPoint.ToString();
            while (!bStop)
            {
                bool b = IsSocketConnected(socket);
                if (!b)
                {
                    break;
                }
                Thread.Sleep(200);
            }
    
            for (int i = 0; i < 3; i++)
            {
                string output;
                RunCmd("arp -d", out output);
                Thread.Sleep(200);
            }
            try
            {
                Thread.Sleep(100);
                if (socket.Connected)
                {
                    socket.Close();
                }
                form1.trace(strip + " 断开了服务器连接.");
            }
            catch
            {
                form1.trace(strip + " 断开了服务器连接.");
            }
            try
            {
                thread.Abort();
            }
            catch(Exception ex)
            {
                string str = ex.Message.ToString();
            }
        }
    
    
        private void RecieveCallBack(IAsyncResult AR)
        {
            try
            {
                Socket RSocket = (Socket)AR.AsyncState;
                int REnd = RSocket.EndReceive(AR);
                RSocket.BeginReceive(recvBuffer, 0, recvBuffer.Length, 0, new AsyncCallback(RecieveCallBack), RSocket);
                //转换  
                string recvMsg = Encoding.ASCII.GetString(recvBuffer, 0, REnd);
                // string recvMsg = Encoding.Unicode.GetString(recvBuffer, 0, REnd);
                HandleMsg(recvMsg);
            }
            catch
            {
                //解析处理结果
                bResult = false;
                bStop = true;
            }
        }
    
    
        private Ret HandleMsg(string msg)
        {
            Ret ret = new Ret(true);
    
            if (msg == "" || msg.Length <= 0)
            {
                ret.b = false;
                ret.str = "接收消息为空";
                //Process.GetCurrentProcess().Kill();
                form1.trace1(ret.str);
                return ret;
    
    
             }
            else
            {          
    
                form1.trace("服务器收到消息:" + msg);
                indexStra = msg.LastIndexOf("#") + 1;//获取最后一个#之后的字符串
                string a = msg.Substring(indexStra, msg.Length - indexStra);
                int b = a.LastIndexOf("\t") + 1;
                getkeymsg = a.Substring(b, a.Length - b);
    
    
                //SET#KEY#字符串长度#字符串
                if (msg.Contains("SET"))
                {
                    if (msg.Contains("FAIL"))
                    {
                        //设置失败:界面展示;发送停止指令
                        form1.trace("设置Key失败");
                        form1.resultDisp("NG", System.Drawing.Color.DarkRed);
                        form1.keyDisp(keyInfo.mainKey);
    
    
                        string cmd = "00#0";
                        sendServerMsg(cmd);
                    }
                    else
                    {
                        //这里可以检测服务器传递过来的KEY是否正确
                        string strSQL = string.Format("select * from  key_info where  key3 = '" + getkeymsg + "' and status = 0 ");//判断数据库里面是是否有该key
                        Ret ret1 = new Ret(true);
                        DBData dd1 = new DBData();
                        ArrayList list1 = new ArrayList();
                        int cnt = dd1.getKeInfo(strSQL, ref list1);
                        if (cnt <= 0)
                        {
                            form1.trace("检查结束 传递服务器传递的KEY值不正确");
                            form1.resultDisp("NG", System.Drawing.Color.Red);
                            form1.keyDisp(keyInfo.mainKey);
                            string cmd = "00#0";
                            sendServerMsg(cmd);
    
                        }
                        //发送GET#KEY#CHECKOK
                        else
                        {
                            string cmd = "GET#KEY#CHECKOK";
                            sendServerMsg(cmd);
                            form1.trace("检查结束 KEY值正确");
    
                        }
                    }
                }
                if (msg.Contains("GET"))
                {
                    if (msg.Contains("FAIL"))
                    {
                        //设置失败:界面展示;发送停止指令
                        form1.trace("设置Key失败");
                        form1.resultDisp("NG", System.Drawing.Color.Red);
    
                        ThreadServer ss = new ThreadServer();
                        ss.End();
    
                    }
                    else
                    {
                        //更新数据库当前Key使用状态
                        ret = updateStatus();
                        if (!ret.b)
                        {
                            form1.trace1("设置Key失败");
                            form1.resultDisp("NG", System.Drawing.Color.Red);
                            ThreadServer ss = new ThreadServer();
                            ss.End();
    
                        }
                        else
                        {
                            form1.trace1("设置Key成功");
                            form1.resultDisp("PASS", System.Drawing.Color.DarkGreen);
                            ThreadServer ss = new ThreadServer();
                            ss.End();
                        }
                    }
                    form1.keyDisp(keyInfo.mainKey);
                    string cmd = "00#0";
                    sendServerMsg(cmd);
                    //
                }
    
                return ret;
            }
        }
    
    
        /// <summary>
        /// 发送消息到客户端(板子)
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        private Ret sendServerMsg(string msg)
        {
            Ret ret = new Ret(true);
            try
            {
                byte[] s = Encoding.ASCII.GetBytes(msg);
               // byte[] s = Encoding.Unicode.GetBytes(msg);
                socket.Send(s, 0, s.Length, 0);
                form1.trace("服务器发送消息:"+msg);
            }
            catch (Exception ey)
            {
                ret.b = false;
                ret.str = ey.Message.ToString();
                form1.trace("服务器发送异常:" + ret.str);
            }
    
            return ret;
        }
    
        #region 解析功能函数
    
        private static string CmdPath = @"C:\Windows\System32\cmd.exe";
        /// <summary>
        /// 执行cmd命令
        /// 多命令请使用批处理命令连接符:
        /// <![CDATA[
        /// &:同时执行两个命令
        /// |:将上一个命令的输出,作为下一个命令的输入
        /// &&:当&&前的命令成功时,才执行&&后的命令
        /// ||:当||前的命令失败时,才执行||后的命令]]>
        /// 其他请百度
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="output"></param>
        public  void RunCmd(string cmd, out string output)
        {
            cmd = cmd.Trim().TrimEnd('&') + "&exit";//说明:不管命令是否成功均执行exit命令,否则当调用ReadToEnd()方法时,会处于假死状态
            using (Process p = new Process())
            {
                p.StartInfo.FileName = CmdPath;
                p.StartInfo.UseShellExecute = false;        //是否使用操作系统shell启动
                p.StartInfo.RedirectStandardInput = true;   //接受来自调用程序的输入信息
                p.StartInfo.RedirectStandardOutput = true;  //由调用程序获取输出信息
                p.StartInfo.RedirectStandardError = true;   //重定向标准错误输出
                p.StartInfo.CreateNoWindow = true;          //不显示程序窗口
                p.Start();//启动程序
    
                //向cmd窗口写入命令
                p.StandardInput.WriteLine(cmd);
                p.StandardInput.AutoFlush = true;
    
                //获取cmd窗口的输出信息
                output = p.StandardOutput.ReadToEnd();
                p.WaitForExit();//等待程序执行完退出进程
                p.Close();
            }
        }
    
        private Ret updateStatus()
        {
            Ret ret = new Ret(true);
    
            try
            {
                string strSQL = string.Format("update key_info set status= 1 where batchId={0} and id={1}", Program.batchInfo.id, keyInfo.id);
                DB db = new DB();
                int cnt = db.executeSQLNonQuery(strSQL);
                if (cnt <= 0)
                {
                    ret.b = false;
                    ret.str = "更新数据库失败";
                }
            }
            catch(Exception ex)
            {
                ret.b = false;
                ret.str = ex.Message.ToString();
            }
    
            return ret; 
        }
    
        private string parseInfo(string info)
        {
            string str = "";
            int index = info.LastIndexOf("#");
            str = info.Substring(index+1);
            return str; 
        }
        /// <summary>
        /// 解析设备ID
        /// </summary>
        /// <param name="stbid"></param>
        /// <returns></returns>
        private string parseMacFromSTBID(string stbid)
        {
            string str = "";
            if (stbid.Length <= 12)
            {
                return str; 
            }
            return  stbid.Substring(stbid.Length-12);
        }
    
        /// <summary>
        /// 统计字符在字符串中出现的次数
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private int StatisticsCount(string str)
        {
            string s = "#";
            int Star = 0;
            int Count = 0;
    
            while (Star != -1)
            {
                Star = str.IndexOf(s, Star);//获取字符的索引
                if (Star != -1)
                {
                    Count++;
                    Star++;
                }
            }
            return Count;
        }
    
    
        #endregion 
    
    }
    

    }

    评论

报告相同问题?

悬赏问题

  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
  • ¥15 让node服务器有自动加载文件的功能
  • ¥15 jmeter脚本回放有的是对的有的是错的
  • ¥15 r语言蛋白组学相关问题
  • ¥15 Python时间序列如何拟合疏系数模型