private void button5_Click(object sender, EventArgs e) { clearButtonColor(); this.button5.ForeColor = Color.Red; this.button5.BackColor = Color.Yellow; if (comboBox_allUVA.Text == "") { return; } foreach (DictionaryEntry dtmpUVA in allUVA) { UvaEntity tmpUVA = dtmpUVA.Value as UvaEntity; if (comboBox_allUVA.Text == tmpUVA.uvaName) { tmpUVA.setBandWidth(6000000); break; } } }
private void comboBox_allUVA_SelectedValueChanged(object sender, EventArgs e) { Trace.WriteLine(comboBox_allUVA.Text); if (((UvaEntity)panel_UVA[Global.MAIN_PANEL]).uvaName == comboBox_allUVA.Text) { Trace.WriteLine("无需交换"); } else { Trace.WriteLine("需要交换"); foreach (string panelName in panel_UVA.Keys) { UvaEntity uvaS = panel_UVA[panelName] as UvaEntity; if (uvaS.uvaName == comboBox_allUVA.Text) { changePanel(Global.MAIN_PANEL, panelName); break; } } } }
/// <summary> /// 视频接收,循环接收视频信息,并保存 /// </summary> /// <param name="obj">UDPclient 用于接收无人机传输视频</param> /*private void videoReceiveLoop(object obj) * { * //获取无人机实例 * UvaEntity uvaClient = obj as UvaEntity; * //获取文件写入名 * String savaFileName = Global.getSavaFileName(uvaClient); * uvaClient.videoFileName = savaFileName; * * videoReceiveThread.IsBackground = true; * 在这个线程中写入文件,会使得文件无法实时更新,而无法播放 * FileStream savaFileStream = null; * try * { * savaFileStream = new FileStream(savaFileName, FileMode.Create); * } * catch (Exception e) * { * * //throw; * Trace.WriteLine(e.ToString()); * } * int sum = 0; * //设置定时器,用于释放资源 * System.Threading.Timer Timer_deleteVideoReceiveLoop = new System.Threading.Timer(deleteVideoReceiveLoop, null, 0, 5000); * while (true) * { * Byte[] receiveBytes; * string receiveData; * if(!uvaClient.fileIsWriting && uvaClient.getActivateTmpVideoQueue().Count>10) * { * try * { * //视频写入线程 * Thread writeToFileThread = new Thread(new ParameterizedThreadStart(sava2FileThread)); * uvaClient.fileIsWriting = true; * uvaClient.changeIndex(); * writeToFileThread.Start(uvaClient); * } * catch (Exception e) * { * * Trace.WriteLine("写入文件线程开启失败"+e.ToString()); * } * * } * //允许接收任意远端发送的消息 * IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0); * //阻塞,只到接收到消息 * try * { * //输出收到的消息总条数 * Trace.WriteLine("总计收到" + sum.ToString()); * receiveBytes = uvaClient.videoReceiveClient.Receive(ref RemoteIpEndPoint); * //写入缓存队列 * uvaClient.addVideSegment(receiveBytes); * //savaFileStream.Write(receiveBytes, 0, receiveBytes.Length); * sum += receiveBytes.Length; * //savaFileStream.Flush(); * receiveData = Encoding.UTF8.GetString(receiveBytes); * //输出debug信息 * //Trace.WriteLine("接收到消息:"+receiveData); * #if DEBUG * textBox_sysLog.Invoke(setSysLogCallBack, ("接收到来自" + RemoteIpEndPoint.ToString() + "消息:" + receiveData)); #endif * } * catch (Exception e) * { * * //throw; * Trace.WriteLine(e.ToString()); * continue; * } * * * } * }*/ /// <summary> /// 将缓存队列中的视频写入文件 /// </summary> /// <param name="obj"></param> public void sava2FileThread(object obj) { //获取无人机实例 UvaEntity uvaClient = obj as UvaEntity; FileStream videoSavaFileStream = null; string videoSavaFile = uvaClient.videoFileName; try { //Trace.WriteLine("写入文件"); fileSem.WaitOne(); videoSavaFileStream = new FileStream(videoSavaFile, FileMode.Append); foreach (Byte[] videoSG in uvaClient.getUnactivateTmpVideoQueue()) { videoSavaFileStream.Write(videoSG, 0, videoSG.Length); } videoSavaFileStream.Flush(); videoSavaFileStream.Close(); videoSavaFileStream = null; fileSem.Release(); uvaClient.clearQueue(); } catch (Exception e) { Trace.WriteLine(e.ToString()); } finally { if (videoSavaFileStream != null) { videoSavaFileStream.Flush(); videoSavaFileStream.Close(); } } sem.WaitOne(); uvaClient.fileIsWriting = false; sem.Release(); }
/// <summary> /// 生成心跳响应的信息 /// </summary> public static Byte[] HeratResponse(UvaEntity uvaT) { UVA_RESPONSE repMsg = new UVA_RESPONSE(); string ip = Global.cpeIP; string[] ips = ip.Split('.'); int ipFirst = Convert.ToInt32(ips[0]); int ipSecond = Convert.ToInt32(ips[1]); int ipThird = Convert.ToInt32(ips[2]); int ipFourth = Convert.ToInt32(ips[3]); repMsg.IPFirst = ipFirst; repMsg.IPSecond = ipSecond; repMsg.IPThird = ipThird; repMsg.IPFourth = ipFourth; //repMsg.Port = uvaT.videoPort; repMsg.Port = Global.cpePort; repMsg.sendType = '\u0002'; repMsg.bandWidth = uvaT.bandWidth; //把ip和端口补充上 /*string[] ips = uvaT.videoIp.Split('.'); * int ipFirst = Convert.ToInt32(ips[0]); * int ipSecond = Convert.ToInt32(ips[1]); * int ipThird = Convert.ToInt32(ips[2]); * int ipFourth = Convert.ToInt32(ips[3]); * * repMsg.sendType = Global.cmdTypeREADY; * repMsg.IPFirst = ipFirst; * repMsg.IPSecond = ipSecond; * repMsg.IPThird = ipThird; * repMsg.IPFourth = ipFourth; * repMsg.Port = uvaT.videoPort;*/ return(StructToBytes(repMsg)); }
/// <summary> /// 生成文件签名 /// </summary> public static string getSavaFileName(UvaEntity uvaClient) { //throw new NotImplementedException(); return(videoSavePath + "UVA_" + uvaClient.id + "_" + DateTime.Now.ToLocalTime().ToString("yyyy_MM_dd_hh_mm_ss") + ".h264"); }
/// <summary> /// /// </summary> /// <param name="sourceUVA">文件来源的UVA</param> /// <param name="segmentIndex">要写入的文件段的序号</param> public VideoSegment(UvaEntity sourceUVA, int segmentIndex) { }
/// <summary> /// 调度循环,用于接收命令,完成调度。 /// </summary> /// <param name="obj"></param> private void dispatchLoop(object obj) { //throw new NotImplementedException(); UdpClient dispatch = obj as UdpClient; BytesManager bmanager = null; #if DEBUG textBox_sysLog.Invoke(setSysLogCallBack, "启动成功"); #endif while (true) { //阻塞,只到接收到消息 Byte[] receiveBytes = null; // dispatch.Receive(ref RemoteIpEndPoint); string receiveData = null; // Encoding.UTF8.GetString(receiveBytes); //允许接收任意远端发送的消息 IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0); try { //阻塞,只到接收到消息 receiveBytes = dispatch.Receive(ref RemoteIpEndPoint); bmanager = new BytesManager(receiveBytes); receiveData = Encoding.UTF8.GetString(receiveBytes); } catch (Exception e) { Trace.WriteLine(e.ToString()); Trace.WriteLine(e.Message); continue; } //输出debug信息 //Trace.WriteLine("接收到消息:"+receiveData); #if DEBUG textBox_sysLog.Invoke(setSysLogCallBack, ("接收到来自" + RemoteIpEndPoint.ToString() + "消息:" + receiveBytes)); //textBox_sysLog.Invoke(setSysLogCallBack, (receiveBytes)); #endif string[] commands = receiveData.Split(';'); if (bmanager.msgForm == (int)Global.msgFromType.uva || bmanager.msgForm == (int)Global.msgFromType.helmet) { switch (bmanager.uvaMsg.sendType) { case '\u0001': { #if DEBUG textBox_sysLog.Invoke(setSysLogCallBack, ("解析到 begin 命令")); #endif //获取无人机id int uvaId = bmanager.uvaMsg.cliNum; //检查是否重复连接 if (allUVA.ContainsKey(uvaId)) { string sendString = "error;DuplicateConnection;"; //Byte[] sendBytes = Encoding.UTF8.GetBytes(sendString); UvaEntity tmpUva = allUVA[uvaId] as UvaEntity; Byte[] sendBytes = Command.DuplicateConnection(tmpUva.videoIp, tmpUva.videoPort); try { dispatch.Send(sendBytes, sendBytes.Length, RemoteIpEndPoint); textBox_sysLog.Invoke(setSysLogCallBack, string.Format("向{0}:{1},{2}号无人机发送错误信息{3}", RemoteIpEndPoint.Address, RemoteIpEndPoint.Port, uvaId, sendString)); } catch (Exception e) { #if DEBUG textBox_sysLog.Invoke(setSysLogCallBack, e.ToString()); #endif textBox_sysLog.Invoke(setSysLogCallBack, string.Format("向{0}:{1},{2}号无人机发送错误信息失败", RemoteIpEndPoint.Address, RemoteIpEndPoint.Port, uvaId)); } break; } //接收到连接信息,输出日志信息 textBox_sysLog.Invoke(setSysLogCallBack, ("接收到来自" + RemoteIpEndPoint + "的连接请求")); //为新的UVA分配接收视频信息的udpClient int restTimes = Global.MAX_RETRY_TIMES; while (true) { if (restTimes > 0) { #if DEBUG textBox_sysLog.Invoke(setSysLogCallBack, ("正在为" + RemoteIpEndPoint.Address + ":" + RemoteIpEndPoint.Port + "分配视频接收服务器")); textBox_sysLog.Invoke(setSysLogCallBack, (string.Format("第{0}/{1}次尝试", Global.MAX_RETRY_TIMES - restTimes + 1, Global.MAX_RETRY_TIMES))); #endif } else { textBox_sysLog.Invoke(setSysLogCallBack, (string.Format("为{0}:{1}分配视频接收服务器失败,系统资源不足", RemoteIpEndPoint.Address, RemoteIpEndPoint.Port))); break; } restTimes--; //获取视频接收服务器的ip地址 string video_receive_ip = Global.RECEIVE_VIDEO_SERVER; //生成端口,检查是否可用 System.Random a = new Random(System.DateTime.Now.Millisecond); // use System.DateTime.Now.Millisecond as seed int RandKey = a.Next(Global.MINPORT, Global.MAXPORT); #if DEBUG textBox_sysLog.Invoke(setSysLogCallBack, string.Format("为{0}:{1}尝试分配端口{2}", RemoteIpEndPoint.Address, RemoteIpEndPoint.Port, RandKey)); #endif try { //分配端口成功,开启新的线程,接收视频信息 UdpClient videoReceiveUDPClient = new UdpClient(new IPEndPoint(IPAddress.Parse("0.0.0.0"), RandKey)); videoReceiveUDPClient.Close(); //记录无人机 UvaEntity tmpUVA = new UvaEntity(RemoteIpEndPoint.Address.ToString(), RemoteIpEndPoint.Port, bmanager.uvaMsg.cliNum, video_receive_ip, RandKey, RemoteIpEndPoint); allUVA.Add(uvaId, tmpUVA); //开启UDP视频接收线程 //videoReceiveThread = new Thread(new ParameterizedThreadStart(videoReceiveLoop)); //videoReceiveThread.IsBackground = true; //videoReceiveThread.Start(tmpUVA); //暂停0.5秒,等待allUVA更新 //System.Threading.Thread.Sleep(500); //分配成功,输出信息 textBox_sysLog.Invoke(setSysLogCallBack, (string.Format("为{0}:{1}分配视频接收服务器成功,视频接收地址为{2}:{3}", RemoteIpEndPoint.Address, RemoteIpEndPoint.Port, video_receive_ip, RandKey))); //在全部无人机combbox里面添加一项 comboBox_allUVA.Invoke(modifyUVACallBack, tmpUVA, true); break; } catch (Exception e) { Trace.WriteLine(e.StackTrace); textBox_sysLog.Invoke(setSysLogCallBack, e.StackTrace.ToString()); textBox_sysLog.Invoke(setSysLogCallBack, e.Message.ToString()); } } break; } case '\u0003': case '\u0004': { #if DEBUG textBox_sysLog.Invoke(setSysLogCallBack, string.Format("接收到{0}信息", bmanager.uvaMsg.sendType == '\u0003'?"end":"ok")); #endif //获取无人机id //int uvaId = Convert.ToInt32(commands[2]); //获取无人机id int uvaId = bmanager.uvaMsg.cliNum; //检查是否重复注销 if (!allUVA.ContainsKey(uvaId)) { string sendString = "error;DuplicatedeDisconnect;"; //Byte[] sendBytes = Encoding.UTF8.GetBytes(sendString); Byte[] sendBytes = Command.Error(Global.DuplicatedeDisconnect); try { dispatch.Send(sendBytes, sendBytes.Length, RemoteIpEndPoint); textBox_sysLog.Invoke(setSysLogCallBack, string.Format("向{0}:{1},{2}号无人机发送错误信息{3}", RemoteIpEndPoint.Address, RemoteIpEndPoint.Port, uvaId, sendString)); } catch (Exception e) { #if DEBUG textBox_sysLog.Invoke(setSysLogCallBack, e.ToString()); #endif textBox_sysLog.Invoke(setSysLogCallBack, string.Format("向{0}:{1},{2}号无人机发送错误信息失败", RemoteIpEndPoint.Address, RemoteIpEndPoint.Port, uvaId)); } break; } //获取无人机实例,进行销毁操作 try { UvaEntity tmpUva = allUVA[uvaId] as UvaEntity; comboBox_allUVA.Invoke(modifyUVACallBack, tmpUva, false); } catch (Exception ee) { Trace.WriteLine(ee.Message); } break; } //收到心跳信息 case '\u0002': { int id = -1; string type = null; string info = null; try { //获取设备的id号 //id = Convert.ToInt32(commands[2]); id = bmanager.uvaMsg.cliNum; //获取设备类型 type = bmanager.uvaMsg.cliType == '\u0001'?"uva": "helmet"; //type = commands[1]; //info = commands[3]; Trace.WriteLine("心跳命令解析完毕" + type + id.ToString()); //string[] infos = info.Split('&'); if (!allUVA.Contains(id)) { Trace.WriteLine(string.Format("{0} {1}已经下线", type, id.ToString())); break; } string x, y, heartTime; try { //x = infos[0]; //y = infos[1]; //heartTime = infos[2]; x = string.Format("{0}_{1}_{2}", bmanager.uvaMsg.latDeg, bmanager.uvaMsg.latMin, bmanager.uvaMsg.latSec); y = string.Format("{0}_{1}_{2}", bmanager.uvaMsg.lonDeg, bmanager.uvaMsg.lonMin, bmanager.uvaMsg.lonSec); heartTime = string.Format("{0}_{1}_{2}", bmanager.uvaMsg.hour, bmanager.uvaMsg.minute, bmanager.uvaMsg.second); UvaEntity tmpUVA = allUVA[id] as UvaEntity; //tmpUVA.receiveHeartAsync(x, y, heartTime); byte[] sendBytes = Command.HeratResponse(tmpUVA); string gpsString = string.Format("{0}{1}{2}{3},{4}{5}{6}{7}", bmanager.uvaMsg.latDeg, bmanager.uvaMsg.latMin, bmanager.uvaMsg.latSec, bmanager.uvaMsg.latDir, bmanager.uvaMsg.lonDeg, bmanager.uvaMsg.lonMin, bmanager.uvaMsg.lonSec, bmanager.uvaMsg.lonDir); dispatch.Send(sendBytes, sendBytes.Length, RemoteIpEndPoint); #if DEBUG Trace.WriteLine(string.Format("Terminal {8} GPS Info:\r\n{0}{1}{2}{3},{4}{5}{6}{7}\r\n", bmanager.uvaMsg.latDeg, bmanager.uvaMsg.latMin, bmanager.uvaMsg.latSec, bmanager.uvaMsg.latDir, bmanager.uvaMsg.lonDeg, bmanager.uvaMsg.lonMin, bmanager.uvaMsg.lonSec, bmanager.uvaMsg.lonDir, id)); textBox_sysLog.Invoke(setSysLogCallBack, string.Format("解析到心跳命令\r\n" + "终端 {0} GPS:{1}\r\n" + "时间 {2}", id, gpsString, heartTime)); #endif if ((allUVA[id] as UvaEntity).panelName == Global.MAIN_PANEL) { labelGPS.Invoke(updateGPSCAllBack, string.Format("{0}{1}{2}{3},{4}{5}{6}{7}", bmanager.uvaMsg.latDeg, bmanager.uvaMsg.latMin, bmanager.uvaMsg.latSec, bmanager.uvaMsg.latDir, bmanager.uvaMsg.lonDeg, bmanager.uvaMsg.lonMin, bmanager.uvaMsg.lonSec, bmanager.uvaMsg.lonDir)); } } catch (Exception e) { Trace.WriteLine("info解析失败"); Trace.WriteLine(e.StackTrace); Trace.WriteLine(e.Message); #if DEBUG textBox_sysLog.Invoke(setSysLogCallBack, e.Message); #endif //throw; } } catch (Exception e) { Trace.WriteLine(e.StackTrace); Trace.WriteLine(e.Message); //throw; } break; } default: break; } } else if (bmanager.msgForm == (int)Global.msgFromType.linkInfo) { linkInfoBoard.setByLinkInfoMsg(bmanager); } } }
/// <summary> /// 修改界面上,在线无人机的回调 /// </summary> /// <param name="UVAInfo">无人机的信息编号</param> /// <param name="add">如果为true,则是增加这条记录,否则是删除记录</param> public void modifyUVA(UvaEntity newUVA, bool add = true) { if (add) { string uvaName = newUVA.uvaName; this.comboBox_allUVA.Items.Add(uvaName); int uvaNum = allUVA.Count; this.label_uvaNum.Text = Convert.ToString(uvaNum); newUVA.setVLCPlayer(); //绑定窗体并播放 newUVA.setRenderWindow(allPanel, panel_UVA); newUVA.vlcPlayer.Play(); //发送ready信息 newUVA.sendReady(); this.comboBox_allUVA.SelectedIndex = this.comboBox_allUVA.FindString(uvaName); } else { //执行无人机下线操作 newUVA.logOut(); //在全部在线的无人机中删掉下线的无人机 allUVA.Remove(newUVA.id); //释放panel panel_UVA.Remove(newUVA.panelName); //更改界面信息 string uvaName = newUVA.uvaName; this.comboBox_allUVA.Items.Remove(uvaName); int uvaNum = allUVA.Count; //如果删除了最后一条项目,则清除一下combbox if (uvaNum == 0) { this.comboBox_allUVA.Text = ""; } this.label_uvaNum.Text = Convert.ToString(uvaNum); //检查panel是否需要更换 if (Global.MAIN_PANEL == newUVA.panelName) { int onlineUVANum = comboBox_allUVA.Items.Count; if (onlineUVANum > 0) { string lastUVAName = comboBox_allUVA.Items[onlineUVANum - 1].ToString(); foreach (UvaEntity tmpUVA in allUVA.Values) { if (tmpUVA.uvaName == lastUVAName) { changePanel(newUVA.panelName, tmpUVA.panelName); this.comboBox_allUVA.SelectedIndex = this.comboBox_allUVA.FindString(tmpUVA.uvaName); Trace.WriteLine(string.Format("{0}下线,{1}替换到大图", newUVA.uvaName, tmpUVA.uvaName)); break; } } } else { Trace.WriteLine("全部无人机都下线了"); } //Trace.WriteLine(lastUVAName); } } }