public void StartLongConnection() { while (IsKeepLongConnection) { try { LongConnectSender = new SocketSender(CurrentRoute.IsNextNodeProxy); LongConnectSender.ConnectWithTimeout(CurrentRoute.NextNode.Address, BuildConnectionTimeout); LongConnectSender.SetTimeout(LongConnectionTimeout, LongConnectionTimeout); if (CurrentRoute.IsNextNodeProxy) { LongConnectSender.SendBytes(SocketPacketFlag.ReversedProxyLongConnectionRequest, CurrentRoute.GetBytes(node_start_index: 1)); LongConnectSender.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, CurrentRoute.ProxyRoute[header.I1], Encoding.UTF8.GetString(bytes))); } } return; } catch (Exception ex) { Log("Start long connection exception : " + ex.Message, LogLevel.Error); } Thread.Sleep(ReconnectInterval); } }
/* * * private bool DoForwardProxy(Socket client, SocketEndPoint socket_ep) * { * socket_ep = AuthenticationProxy(client); * int error_count = 0; * while (error_count < 5) * { * try * { * byte[] proxy_header = ReceiveProxyHeader(client); * HB32Header recv_header; * byte[] recv_bytes; * * switch ((ProxyHeader)proxy_header[1]) * { * case ProxyHeader.SendHeader: * SocketIO.ReceiveBytes(client, out recv_header, out recv_bytes); * socket_ep.SendHeader(recv_header); * if (recv_header.Flag == SocketPacketFlag.DisconnectRequest) * { * DisposeClient(client, socket_ep); * return true; * } * break; * case ProxyHeader.SendBytes: * SocketIO.ReceiveBytes(client, out recv_header, out recv_bytes); * socket_ep.SendBytes(recv_header, recv_bytes); * break; * case ProxyHeader.ReceiveBytes: * socket_ep.ReceiveBytes(out recv_header, out recv_bytes); * SocketIO.SendBytes(client, recv_header, recv_bytes); * break; * } * * error_count = 0; * } * catch (SocketException ex) * { * error_count++; * switch (ex.ErrorCode) * { * // 远程 client 主机关闭连接 * case 10054: * DisposeClient(client, socket_ep); * Log("Connection closed (client closed). " + ex.Message, LogLevel.Info); * return false; * // Socket 超时 * case 10060: * Thread.Sleep(200); * Log("Socket timeout. " + ex.Message, LogLevel.Trace); * continue; * default: * Log("Server receive data :" + ex.Message, LogLevel.Warn); * continue; * } * } * catch (Exception ex) * { * error_count++; * if (ex.Message.Contains("Buffer receive error: cannot receive package")) * { * DisposeClient(client, socket_ep); * Log(ex.Message, LogLevel.Trace); * return false; * } * if (ex.Message.Contains("Invalid socket header")) * { * DisposeClient(client, socket_ep); * Log("Connection closed : " + ex.Message, LogLevel.Warn); * return false; * } * Log("Server exception :" + ex.Message, LogLevel.Warn); * Thread.Sleep(200); * continue; * } * } * return false; * } */ /// <summary> /// 完成创建 Socket 过程身份认证的代理过程 /// </summary> /// <param name="client"></param> /// <returns>已与Server或下级代理连接成功的 SocketEndPoint 对象</returns> private SocketSender AuthenticationProxy(Socket client) { // todo 重写 21.05.28 byte[] proxy_header; SocketIO.ReceiveBytes(client, out HB32Header route_header, out byte[] route_bytes); Debug.Assert(route_bytes[0] == 1); int pt = 0; ConnectionRoute route = ConnectionRoute.FromBytes(route_bytes, ref pt); byte[] key_bytes = new byte[route_bytes.Length - pt]; Array.Copy(route_bytes, pt, key_bytes, 0, key_bytes.Length); SocketSender proxy_client = new SocketSender(null, route.IsNextNodeProxy); byte[] bytes_to_send = new byte[0]; // todo // todo 异常处理 if (route.NextNode.Address.Equals(this.HostAddress)) { /// 下级为挂载在此的反向代理 /// 利用与反向代理的长连接新建 socket 并通信 } else { /// 下级需正向代理 proxy_client.Connect(route.NextNode.Address, Config.SocketSendTimeout, Config.SocketReceiveTimeout); } proxy_client.SendBytes(route_header, bytes_to_send); if (proxy_client.IsRequireProxyHeader) { ReceiveProxyHeader(client); } proxy_client.ReceiveBytes(out HB32Header auth_header, out byte[] auth_bytes); //SocketIO.SendBytes(client, auth_header, auth_bytes); return(proxy_client); /* * * * GetAimInfo(route_bytes, out TCPAddress AimAddress, out bool IsAimProxy, out byte[] AimBytes); * SocketClient socket_client = new SocketClient(AimAddress); * socket_client.IsWithProxy = IsAimProxy; * try * { * socket_client.Connect(Config.SocketSendTimeOut, Config.SocketReceiveTimeOut); * socket_client.SendBytes(route_header, AimBytes); * } * catch(Exception ex) * { * proxy_header = ReceiveProxyHeader(client); * this.SendBytes(client, SocketPacketFlag.AuthenticationException, "Proxy connect to server failed."); * throw new Exception("Cannot connect to server : " + ex.Message); * } * proxy_header = ReceiveProxyHeader(client); * socket_client.ReceiveBytes(out HB32Header auth_header, out byte[] auth_bytes); * this.SendBytes(client, auth_header, auth_bytes); * return socket_client; */ }
/// <summary> /// 当上一级代理不是挂载在当前代理上的节点上时, 利用此方法完成同方向代理的中继, 并返回上级代理结果 /// </summary> /// <param name="responder"></param> /// <param name="route"></param> /// <returns></returns> private SocketSender ConnectionRelay(SocketResponder responder, HB32Header header, ConnectionRoute route) { if (route.IsNextNodeProxy) { /// 继续正向代理 SocketSender sender = new SocketSender(true); string err_msg = ""; try { sender.ConnectWithTimeout(route.NextNode.Address, Config.BuildConnectionTimeout); sender.SetTimeout(Config.SocketSendTimeout, Config.SocketReceiveTimeout); } catch (Exception ex) { /// 当前代理建立连接失败 err_msg = ex.Message; } if (string.IsNullOrEmpty(err_msg)) { HB32Header next_header = header.Copy(); next_header.I1++; sender.SendBytes(next_header, route.GetBytes(node_start_index: 1)); sender.ReceiveBytes(out HB32Header respond_header, out byte[] respond_bytes); if ((respond_header.Flag | SocketPacketFlag.ExceptionFlag) == 0) { responder.SendHeader(respond_header); } else { /// 上级或更上级代理建立连接失败, header 中包含抛出异常的代理位置 responder.SendBytes(respond_header, respond_bytes); } } else { HB32Header err_header = header.Copy(); err_header.Flag = (SocketPacketFlag)(((int)err_header.Flag & 0xFFFF00) | 0x90); responder.SendBytes(err_header, err_msg); } return(sender); } else { /// 直连 server SocketSender sender = new SocketSender(false); string err_msg = ""; try { sender.ConnectWithTimeout(route.ServerAddress.Address, Config.BuildConnectionTimeout); sender.SetTimeout(Config.SocketSendTimeout, Config.SocketReceiveTimeout); } catch (Exception ex) { err_msg = ex.Message; } /// response if (string.IsNullOrEmpty(err_msg)) { HB32Header resp_header = header.Copy(); resp_header.Flag = (SocketPacketFlag)(((int)resp_header.Flag & 0xFFFF00) | 0x10); responder.SendHeader(resp_header); } else { HB32Header err_header = header.Copy(); err_header.Flag = (SocketPacketFlag)(((int)err_header.Flag & 0xFFFF00) | 0x90); responder.SendBytes(err_header, err_msg); } return(sender); } }