void args_Completed(object sender, SocketAsyncEventArgs e) { if (ConnectionInfo.CurrentServer != null && ConnectionInfo.CurrentServer.IsConnected) { SocketAsyncEventArgs args = null; UserToken userToken = null; PacketInfo packetInfo = null; if (e.SocketError != SocketError.Success) { return; } //데이터 사용량 누적 if (e.BytesTransferred > 0) { AppLoader.CellularDataUtil.SumUsageCellularData(e.BytesTransferred); } //이미지를 받다가 커넥션이 끊길때 에러 방지를 위해 if (ConnectionInfo.TcpSocket.Connected && ConnectionInfo.CurrentServer != null && ConnectionInfo.CurrentServer.IsConnected && this.IsRealTimeScreen) { switch (e.LastOperation) { case SocketAsyncOperation.SendTo: if (imageUdpSocket != null) { userToken = e.UserToken as UserToken; packetInfo = userToken.PacketInfo; byte[] buff = new byte[Constant.UDP_BUFFER_SIZE]; UserToken ut = new UserToken(packetInfo, userToken.callback); args = new SocketAsyncEventArgs(); args.UserToken = ut; args.RemoteEndPoint = new IPEndPoint(IPAddress.Parse(ConnectionInfo.CurrentServer.ServerIP), ConnectionInfo.CurrentServer.UdpPort);; args.SetBuffer(buff, 0, Constant.UDP_BUFFER_SIZE); args.Completed += args_Completed; _clientDone.Reset(); imageUdpSocket.ReceiveFromAsync(args); bool ret = _clientDone.WaitOne(1000); //1초 동안 수신을 대기함. if (!ret || ImageQualityType != packetInfo.ImageQualityType) { //실패한 소켓 수신객체의 콜백 삭제 args.Completed -= args_Completed; //이미지 수신 실패 이벤트 발생 OnImageReceiveFailed(ImageQualityType != packetInfo.ImageQualityType); } } break; case SocketAsyncOperation.ReceiveFrom: if (e.BytesTransferred > PACKET_FRAME_SIZE) { byte[] rcvbuff = e.Buffer; int header = BitConverter.ToInt32(rcvbuff, 0); int totSize = BitConverter.ToInt32(rcvbuff, 4); int packetSize = BitConverter.ToInt32(rcvbuff, 8); int seq = BitConverter.ToInt32(rcvbuff, 12); bool isXor = Convert.ToBoolean(BitConverter.ToInt32(rcvbuff, 16)); int footer = BitConverter.ToInt32(rcvbuff, 20 + packetSize); if (totSize == 0 || packetSize == 0) { System.Diagnostics.Debug.WriteLine("패킷이 0인 경우 => 발생하면 안되는데..."); Thread.Sleep(300); break; } if (totalSize != totSize && totSize > 0 && totalSize > 0) { System.Diagnostics.Debug.WriteLine("수신 실패이후 다시 시작전에 받아진 데이터 .... 무시하고 넘어감"); break; } //System.Diagnostics.Debug.WriteLine(seq + "번 이미지 수신"); if (header == Constant.PACKET_VELOSTEP_HEADER && //헤더 체크 totalSize < 10 * 1024 * 1024 && // 10MB미만만 허용 packetSize > 0 && seq >= 0 && footer == Constant.PACKET_VELOSTEP_FOOTER) { if (seq == 0 || currImgBytes == null) { totalSize = totSize; currImgBytes = new byte[totalSize]; } //이미지 데이터 복사 Buffer.BlockCopy(e.Buffer, 20, currImgBytes, (Constant.UDP_BUFFER_SIZE - PACKET_FRAME_SIZE) * seq, packetSize); //System.Diagnostics.Debug.WriteLine("전송된길이:{0}, 시퀀스:{1}, 패킷길이:{2}, 현재쓸포인터{3}", new object[] { e.BytesTransferred, seq, packetSize, (Constant.UDP_BUFFER_SIZE - PACKET_FRAME_SIZE) * seq }); if (seq * (Constant.UDP_BUFFER_SIZE - PACKET_FRAME_SIZE) + packetSize >= totalSize) { //완료 seq = 0; totalSize = 0; isRefreshAll = false; userToken = e.UserToken as UserToken; //이미지 화면 표시 요청 ((CallbackHandler)userToken.callback)(new ImageInfo() { IsXorImage = isXor, ImageBytes = currImgBytes }); } else { seq++; } //이전 토큰 userToken = e.UserToken as UserToken; //신규 패킷 packetInfo = new PacketInfo(); packetInfo.PacketType = PacketTypes.RequestImage; packetInfo.DeviceType = DeviceType; packetInfo.ButtonType = ButtonTypes.None; packetInfo.AccessCode = ConnectionInfo.CurrentServer.AccessCode; //seq가 0인 경우만 이미지 품질 재적용 packetInfo.ImageQualityType = seq == 0 ? ImageQualityType : userToken.PacketInfo.ImageQualityType; packetInfo.Seq = seq; packetInfo.Flag = isRefreshAll ? 1 : 0; //xor auto byte[] packet = packetInfo.CachedPacket; args = new SocketAsyncEventArgs(); args.UserToken = new UserToken(packetInfo, userToken.callback); args.SetBuffer(packet, 0, packet.Length); args.Completed += args_Completed; args.RemoteEndPoint = e.RemoteEndPoint; //이벤트 시그널 _clientDone.Set(); //다음 받기 요청 imageUdpSocket.SendToAsync(args); lastReceiveSeq = seq; //if (seq > 0) //{ // //System.Diagnostics.Debug.WriteLine(lastReceiveSeq + "번 이미지 요청."); //} //if (seq == 0) //{ // System.Diagnostics.Debug.WriteLine("다시시작......................."); // System.Diagnostics.Debug.WriteLine(stw.ElapsedMilliseconds); //} //else //{ // System.Diagnostics.Debug.WriteLine(stw.ElapsedMilliseconds); //} } else { System.Diagnostics.Debug.WriteLine("패킷이 잘못된 경우"); } } else { System.Diagnostics.Debug.WriteLine("화면 변경 없음"); } break; } } } }
void udpSockArgs_Completed(object sender, SocketAsyncEventArgs e) { //소켓 결과가 성공이면 받을 준비 if (e.SocketError == SocketError.Success) { //데이터 사용량 누적 if (e.BytesTransferred > 0) { AppLoader.CellularDataUtil.SumUsageCellularData(e.BytesTransferred); } switch (e.LastOperation) { case SocketAsyncOperation.SendTo: Deployment.Current.Dispatcher.BeginInvoke(() => { //입력 비활성화 findServerBtn.IsEnabled = false; portTxtBox.IsEnabled = false; ItemViewOnPage.IsEnabled = false; //진행상태 표시 UIUtils.SetVisibility(labelProgressBar, true); UIUtils.SetVisibility(findProgressBar, true); try { //검색 로딩창 표시 bw.RunWorkerAsync(); } catch (InvalidOperationException ex) { System.Diagnostics.Debug.WriteLine(ex.Message); } int port = ((DnsEndPoint)e.RemoteEndPoint).Port; byte[] buffer = new byte[128]; e.SetBuffer(buffer, 0, buffer.Length); e.RemoteEndPoint = new IPEndPoint(IPAddress.Any, port); udpSocket.ReceiveFromAsync(e); }); break; case SocketAsyncOperation.ReceiveFrom: ServerInfo serverInfo = PacketUtils.ResolveServerPacket(PacketTypes.FindServer, e) as ServerInfo; if (serverInfo != null) { Deployment.Current.Dispatcher.BeginInvoke(() => { //수신된 서버 추가 serverInfoList.Add(serverInfo); if (currentHostname.Contains(".")) { string host = currentHostname.Substring(currentHostname.LastIndexOf(".") + 1); if (host == "255") { //나머지 수신 대기 udpSocket.ReceiveFromAsync(e); } } try { //수신이 되면 bw 취소 if (bw.WorkerSupportsCancellation) { bw.CancelAsync(); } } catch (InvalidOperationException ex) { System.Diagnostics.Debug.WriteLine(ex.Message); } }); } break; } } else { Deployment.Current.Dispatcher.BeginInvoke(() => { switch (e.SocketError) { case SocketError.HostNotFound: MessageBox.Show(I18n.GetString("AppMessageNotFoundHost"), I18n.GetString("AppMessageNotification"), MessageBoxButton.OK); break; case SocketError.HostUnreachable: case SocketError.NetworkUnreachable: case SocketError.AccessDenied: MessageBox.Show(I18n.GetString("AppMessageUnreachableHost"), I18n.GetString("AppMessageNotification"), MessageBoxButton.OK); break; default: break; } hostTxtBox.Focus(); }); } }