/// <summary> /// 发送指令 /// </summary> private void SendCmd(VideoTransferProtocolKey protocolKey) { lock (queueLocker) { tcpSendQueue.Enqueue(protocolKey); } }
/// <summary> /// 处理TCP接收的数据 /// </summary> /// <param name="datas">所收数据</param> private void DealWithTcpTransferRecieveDatas(byte[] datas) { if (datas.Length < 4) { return; // 长度不可能出现 } if (datas[0] != (byte)VideoTransferProtocolKey.Header1 || datas[1] != (byte)VideoTransferProtocolKey.Header2) { return; // 协议头不匹配 } byte deviceIndex = datas[2]; VideoTransferProtocolKey workCmd = (VideoTransferProtocolKey)datas[3]; switch (workCmd) { case VideoTransferProtocolKey.RSAKey: int keyLength = Convert.ToInt32( IPAddress.NetworkToHostOrder( BitConverter.ToInt32(datas, 4))); if (keyLength != datas.Length - 8) { return; // 长度不匹配 } remoteDeviceIndex = deviceIndex; remoteDevicePublicKey = Encoding.UTF8.GetString(datas, 8, keyLength); Logger.HistoryPrinting(Logger.Level.INFO, MethodBase.GetCurrentMethod().DeclaringType.FullName, "RSAKey saved."); // 发送AES密钥 SendAESKey(); Logger.HistoryPrinting(Logger.Level.INFO, MethodBase.GetCurrentMethod().DeclaringType.FullName, "AESKey sent."); break; case VideoTransferProtocolKey.BeginTransferVideo: if (!ifGetVideoSendCmdOnce && remoteDeviceIndex == deviceIndex) { // 若未收到过发送视频指令 打开UDP传输定时器 ifGetVideoSendCmdOnce = true; camera = new Capture(cameraIndex); camera.SetCaptureProperty(CapProp.Fps, cameraFps); camera.SetCaptureProperty(CapProp.FrameHeight, cameraHeight); camera.SetCaptureProperty(CapProp.FrameWidth, cameraWidth); // 重置标志 udpTransferSendQueue.Clear(); packIndex = 0; udpSendClocker.Start(); udpTransferCancel = new CancellationTokenSource(); udpTransferSendTask = new Task(() => UdpTransferSendTaskWork(udpTransferCancel.Token)); udpTransferSendTask.Start(); Logger.HistoryPrinting(Logger.Level.INFO, MethodBase.GetCurrentMethod().DeclaringType.FullName, "Begin send video."); } break; case VideoTransferProtocolKey.PingSignal: if (remoteDeviceIndex != deviceIndex) { return; // 设备号不匹配 } tcpBeatClocker.Stop(); tcpBeatClocker.Start(); break; case VideoTransferProtocolKey.EndTransferVideo: if (ifGetVideoSendCmdOnce && remoteDeviceIndex == deviceIndex) { // 若收到过发送视频指令 准备关闭连接 EndAllLoop(); Logger.HistoryPrinting(Logger.Level.INFO, MethodBase.GetCurrentMethod().DeclaringType.FullName, "End send video."); } break; default: Logger.HistoryPrinting(Logger.Level.INFO, MethodBase.GetCurrentMethod().DeclaringType.FullName, "No such control command."); break; } }
/// <summary> /// TCP发送队列数据任务 /// </summary> /// <param name="cancelFlag">停止标志</param> private void TcpTransferSendTaskWork(CancellationToken cancelFlag) { Logger.HistoryPrinting(Logger.Level.INFO, MethodBase.GetCurrentMethod().DeclaringType.FullName, "WinForm video client tcp transfer begins to send datas."); while (true) { if (cancelFlag.IsCancellationRequested) { break; } Thread.Sleep(sleepMsForQueueSend); VideoTransferProtocolKey waitSentKey = VideoTransferProtocolKey.VideoTransfer; lock (queueLocker) { if (tcpSendQueue.Count > 0) { waitSentKey = tcpSendQueue.Dequeue(); } } if (waitSentKey == VideoTransferProtocolKey.VideoTransfer) { continue; } List <byte> sendBytes = new List <byte>(4); sendBytes.Add((byte)VideoTransferProtocolKey.Header1); sendBytes.Add((byte)VideoTransferProtocolKey.Header2); sendBytes.Add(clientDeviceIndex); sendBytes.Add((byte)waitSentKey); if (waitSentKey == VideoTransferProtocolKey.RSAKey) { byte[] publicKeyBytes = Encoding.UTF8.GetBytes(publicKey); sendBytes.AddRange(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(publicKeyBytes.Length))); sendBytes.AddRange(publicKeyBytes); } try { tcpTransferSocket.Send(sendBytes.ToArray()); } catch (SocketException ex) { if (ex.SocketErrorCode == SocketError.ConnectionReset || ex.SocketErrorCode == SocketError.ConnectionAborted || ex.SocketErrorCode == SocketError.TimedOut) { EndAllLoop(); Logger.HistoryPrinting(Logger.Level.INFO, MethodBase.GetCurrentMethod().DeclaringType.FullName, "WinForm video client tcp transfer send datas failed.", ex); } else { Logger.HistoryPrinting(Logger.Level.WARN, MethodBase.GetCurrentMethod().DeclaringType.FullName, "Not deal exception.", ex); throw ex; } } Logger.HistoryPrinting(Logger.Level.INFO, MethodBase.GetCurrentMethod().DeclaringType.FullName, "WinForm video client tcp transfer send cmd '" + waitSentKey.ToString() + "'."); } FinishAllConnection(); ifTcpConnectionEstablished = false; Logger.HistoryPrinting(Logger.Level.INFO, MethodBase.GetCurrentMethod().DeclaringType.FullName, "WinForm video client tcp transfer stops to send datas."); }