最近遇到了个问题,主要是在做一个异步通讯的时候会一直循环在某个代码段,始终无法跳出,还望各位大神给个建议
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时间序列如何拟合疏系数模型