/// <summary> /// map out a route from shape1 to shape2, starting from a specific side of shape1. /// </summary> /// <param name="InCanvas"></param> /// <param name="Shape1"></param> /// <param name="Shape2"></param> /// <param name="DepartureSide"></param> /// <param name="Route"></param> public static void DrawRouteBetweenShapes( this Canvas InCanvas, Shape Shape1, Shape Shape2, WhichSide DepartureSide, ConnectionRoute Route) { // vertical and horizontal intersection of the two shapes. var vi = ShapeExt.VerticalIntersect(Shape1, Shape2); var hi = ShapeExt.HorizontalIntersect(Shape1, Shape2); if (DepartureSide == WhichSide.Left) { LineCoordinates coor = null; if (Shape1.IsEntirelyToTheRightOf(Shape2).GetValueOrDefault() && (vi.Length > 0)) { coor = InCanvas.DrawLineBetweenShapes( Shape1, WhichSide.Left, Shape2, WhichSide.Right); } else { // draw a short line from the shape to the next available orbit location // around the from shape. var leg = ConnectionLeg.DrawLegToOrbit(Shape1, DepartureSide); Route.AddLeg(leg); } } }
public static ConnectionRoute DrawRouteBetweenShapes( this Canvas InCanvas, Shape Shape1, Shape Shape2) { ConnectionRoute selectedRoute = null; // for each direction from the from shape. var possibleRoutes = new List <ConnectionRoute>(); foreach (var dir in WhichDirectionExt.Directions()) { var side = new ShapeSide(Shape1, dir.ToSide()); var route = new ConnectionRoute(side, Shape2); { var leg = route.DrawInitialLegToShape(); if (leg == null) { continue; } route.AddLeg(leg); } while (true) { if (Shape2.Intersects(route.LastLeg.End)) { break; } var leg = route.DrawLegToShape(); route.AddLeg(leg); } // add the route to the possible routes list. possibleRoutes.Add(route); } // select the route with the fewest number of legs. foreach (var route in possibleRoutes) { if (selectedRoute == null) { selectedRoute = route; } else if (route.LegCount < selectedRoute.LegCount) { selectedRoute = route; } } if (selectedRoute != null) { InCanvas.DrawLinesOfRoute(selectedRoute); Shape1.StoreConnection(selectedRoute, Shape2); Shape2.StoreConnection(selectedRoute, Shape1); } return(selectedRoute); }
public static ConnectionRoute StartConnectionRouteToShape( Shape FromShape, WhichSide StartSide, Shape ToShape) { var fromSide = new ShapeSide(FromShape, StartSide); ConnectionRoute route = new ConnectionRoute(fromSide, ToShape); return(route); }
public static void RemoveLinesOfRoute(this Canvas InCanvas, ConnectionRoute Route) { foreach (var leg in Route.LegList) { var line = leg.DrawnLine; InCanvas.Children.Remove(line); } }
public static void DrawLinesOfRoute(this Canvas InCanvas, ConnectionRoute Route) { foreach (var leg in Route.LegList) { var line = InCanvas.DrawLine(leg.LineCoor); leg.DrawnLine = line; } }
/// <summary> /// 加载当前任务 /// </summary> public void LoadXml() { if (!File.Exists(RecordPath)) { System.Windows.Forms.MessageBox.Show(RecordPath + "do not exist"); return; } XDocument doc = XDocument.Load(RecordPath); XElement root = doc.Root; /// Index XElement idx = root.Element("index"); CurrentTaskIndex = int.Parse(idx.Element("current").Value); /// Tasks XElement tasks = root.Element("taskCollection"); foreach (XElement task in tasks.Elements("task")) { FileTask fileTask = new FileTask(); fileTask.Route = ConnectionRoute.FromBytes(Convert.FromBase64String(task.Element("Route").Value)); fileTask.IsDirectory = bool.Parse(task.Element("IsDirectory").Value); fileTask.Type = (TransferType)Enum.Parse(typeof(TransferType), task.Element("Type").Value); fileTask.RemotePath = task.Element("RemotePath").Value; fileTask.LocalPath = task.Element("LocalPath").Value; fileTask.Length = long.Parse(task.Element("Length").Value); fileTask.Status = (FileTaskStatus)Enum.Parse(typeof(FileTaskStatus), task.Element("Status").Value); fileTask.FinishedPacket = int.Parse(task.Element("FinishedPacket").Value); FileTasks.Add(fileTask); } /// Length /* * XElement len = root.Element("length"); * CurrentLength = long.Parse(len.Element("currentLength").Value); * CurrentFinished = long.Parse(len.Element("currentFinished").Value); * TotalLength = long.Parse(len.Element("totalLength").Value); * PrevBytesAddup = long.Parse(len.Element("taskAddup").Value); */ CurrentLength = FileTasks[CurrentTaskIndex].Length; CurrentFinished = FileTasks[CurrentTaskIndex].FinishedPacket * HB32Encoding.DataSize; TotalLength = 0; PrevBytesAddup = 0; for (int i = 0; i < FileTasks.Count; ++i) { TotalLength += FileTasks[i].Length; if (i < CurrentTaskIndex) { PrevBytesAddup += FileTasks[i].Length; } } Logger.Log("Loaded record.", LogLevel.Info); }
public static SocketClient GenerateConnectedSocketClient(ConnectionRoute route) { SocketClient client = new SocketClient(route.NextNode, route.IsNextNodeProxy); //client.Connect(Config.SocketSendTimeout, Config.SocketReceiveTimeout); client.ConnectWithTimeout(Config.BuildConnectionTimeout); client.SetTimeout(Config.SocketSendTimeout, Config.SocketReceiveTimeout); if (route.IsNextNodeProxy) { /// 向代理服务器申请建立与服务端通信隧道, 并等待隧道建立完成 client.SendBytes(SocketPacketFlag.ProxyRouteRequest, route.GetBytes(node_start_index: 1)); client.ReceiveBytesWithHeaderFlag(SocketPacketFlag.ProxyResponse); } /// 获取 socket 权限 client.SendBytes(SocketPacketFlag.AuthenticationRequest, Config.KeyBytes); client.ReceiveBytesWithHeaderFlag(SocketPacketFlag.AuthenticationResponse); return(client); }
/// <summary> /// 建立连接, (如通信需要经过代理, 会向代理发送后续路由信息并等待代理隧道建立完成) /// 而后发送 KeyBytes 获取 SocketIdentity /// 返回经过认证后的 SocketClient /// </summary> /// <param name="route"></param> /// <param name="maxTry"></param> /// <param name="retryInterval"></param> /// <returns></returns> public static SocketClient GenerateConnectedSocketClient(ConnectionRoute route, int maxTry, int retryInterval = 3000) { int tryCount = 0; string err_msg = ""; while (true) { if (maxTry > 0 && tryCount >= maxTry) { throw new ArgumentException("Generating valid socket failed : exceed max try times.\n" + err_msg); } try { return(GenerateConnectedSocketClient(route)); } catch (Exception ex) { err_msg += ex.Message + "\n"; tryCount++; Thread.Sleep(retryInterval); } } }
public static void StoreConnection( this Shape Shape, ConnectionRoute Route, Shape ToShape) { if (Shape.Tag == null) Shape.Tag = new DrawMore(Shape); // error if the Tag does not contain a DrawMore object. if ((Shape.Tag is DrawMore) == false) { throw new ApplicationException("shape tag is not DrawMore object"); } // ShapeConnection object stores the shape connected to and the line that makes // the connection. ShapeConnection sc = new ShapeConnection() { ConnectRoute = Route, ToShape = ToShape }; // add to the list of connected to shapes. (Shape.Tag as DrawMore).ConnectedToShapes.Add(sc); }
private void ButtonConnect_Click(object sender, RoutedEventArgs e) { if (IsConnecting) { return; } try { SocketFactory.CurrentRoute = ConnectionRoute.FromString(this.TextBoxIP.Text, this.TextBoxProxy.Text, Config.DefaultServerPort, Config.DefaultProxyPort); } catch (Exception) { SocketFactory.CurrentRoute = null; MessageBox.Show("Invalid address syntax"); Logger.Log("Invalid address syntax : " + this.TextBoxIP.Text, LogLevel.Warn); return; } try { IsConnecting = true; Logger.Log("Start connection to " + this.TextBoxIP.Text, LogLevel.Info); this.ButtonConnect.Content = "Connecting ..."; //SocketIdentity identity = SocketFactory.AsyncConnectForIdentity(AsyncConnect_OnSuccess, AsyncConnect_OnException); SocketFactory.AsyncConnectForIdentity(AsyncConnect_OnSuccess, AsyncConnect_OnException); } catch (Exception ex) { /// AsyncConnect 的异常在上面的 SocketAsyncExceptionCallback 中处理 /// 这里的代码应该不会执行 SocketFactory.CurrentRoute = null; Logger.Log("[Not expected exception] Connection to " + this.TextBoxIP.Text + " failed. " + ex.Message, LogLevel.Info); MessageBox.Show(ex.Message); IsConnecting = false; } /// 这里如果写 finally 的话, 会执行于异步代码 AsyncConnect 之前 /// 所以不应在这里用 finally 处理, 后续处理应该写进 AysncConnect 的代理方法内 }
public SocketReversedServer(ConnectionRoute route) { RouteToProxy = route.Copy(); maintainer = new SocketLongConnectionMaintainer(route); }
public static void AsyncConnectForIdentity(ConnectionRoute route, SocketAsyncCallbackEventHandler asyncCallback, SocketAsyncExceptionEventHandler exceptionCallback) { Task.Run(() => { try { SocketIdentity identity = SocketIdentity.None; SocketClient client = new SocketClient(route.NextNode, route.IsNextNodeProxy); //client.Connect(Config.SocketSendTimeout, Config.SocketReceiveTimeout); client.ConnectWithTimeout(Config.BuildConnectionTimeout); client.SetTimeout(Config.SocketSendTimeout, Config.SocketReceiveTimeout); if (route.IsNextNodeProxy) { /// 向代理服务器申请建立与服务端通信隧道, 并等待隧道建立完成 client.SendBytes(SocketPacketFlag.ProxyRouteRequest, route.GetBytes(node_start_index: 1), i1: 0); client.ReceiveBytes(out HB32Header header, out byte[] bytes); if (header.Flag != SocketPacketFlag.ProxyResponse) { throw new Exception(string.Format("Proxy exception at depth {0} : {1}. {2}", header.I1, route.ProxyRoute[header.I1], Encoding.UTF8.GetString(bytes))); } } /// 获取 socket 权限 client.SendBytes(SocketPacketFlag.AuthenticationRequest, Config.KeyBytes); client.ReceiveBytesWithHeaderFlag(SocketPacketFlag.AuthenticationResponse, out HB32Header auth_header); identity = (SocketIdentity)auth_header.I1; client.Close(); asyncCallback.Invoke(null, EventArgs.Empty); } catch (Exception ex) { exceptionCallback.Invoke(null, new SocketAsyncExceptionEventArgs(ex)); } }); /* * * 原来这种方案同样是异步执行, 总会提前返回 SocketIdentity.None * SocketIdentity identity = SocketIdentity.None; * SocketClient client = new SocketClient(route.NextNode, route.IsNextNodeProxy); * client.SocketAsyncCallback += (object sender, EventArgs e) => * { * if (route.IsNextNodeProxy) * { * /// 向代理服务器申请建立与服务端通信隧道, 并等待隧道建立完成 * client.SendBytes(SocketPacketFlag.ProxyRouteRequest, route.GetBytes(node_start_index: 1)); * client.ReceiveBytesWithHeaderFlag(SocketPacketFlag.ProxyResponse); * } * /// 获取 socket 权限 * client.SendBytes(SocketPacketFlag.AuthenticationRequest, Config.KeyBytes); * client.ReceiveBytesWithHeaderFlag(SocketPacketFlag.AuthenticationResponse, out HB32Header header); * identity = (SocketIdentity)header.I1; * client.Close(); * }; * client.SocketAsyncCallback += asyncCallback; * client.SocketAsyncException += exceptionCallback; * client.AsyncConnect(Config.SocketSendTimeout, Config.SocketReceiveTimeout); */ }