public void OnPackageReceived(object sender, PackageEventArgs <ClientPackageInfo> e) { Task.Run(() => { //先gzip压缩 再转为16进制字符串 var body = DataHelper.Compress(e.Package.Data); var pack = new PackJson() { Host = PackJson.Host, UserId = PackJson.UserId, Content = body }; var json = JsonHelper.Instance.Serialize(pack); var jsonBytes = Encoding.UTF8.GetBytes(json); //03 02 数据长度(4) 正文数据(n) ---tcp响应包 var sendBytes = new List <byte>() { 0x3, 0x2 }; sendBytes.AddRange(BitConverter.GetBytes(jsonBytes.Length).Reverse()); sendBytes.AddRange(jsonBytes); //转发给服务器 NatClient.Send(sendBytes.ToArray()); HandleLog.WriteLine($"<---- {PackJson.UserId} 收到报文{e.Package.Data.Length}字节"); }); }
static void OnClientConnected(Socket socket) { //发送注册包给服务端 var pack = PackHelper.CreatePack(new JsonData() { Type = (int)JsonType.NAT, Action = (int)NatAction.Connect, Data = Secret }); NatClient?.Send(pack); }
static void OnClientConnected(object sender, EventArgs e) { //HandleLog.WriteLine($"【{NatClient.LocalEndPoint}】已连接到服务器【{NatClient.Socket.RemoteEndPoint}】"); //发送注册包 var packBytes = new List <byte>() { 0x1, 0x1 }; var lenBytes = BitConverter.GetBytes(RegPack.Length).Reverse(); packBytes.AddRange(lenBytes); packBytes.AddRange(RegPack); NatClient.Send(packBytes.ToArray()); }
static void SendHeart() { while (IsReConnect) { Thread.Sleep(50000); if (NatClient.IsConnected) { //发送心跳包给服务端 var pack = PackHelper.CreatePack(new JsonData() { Type = (int)JsonType.NAT, Action = (int)NatAction.Heart, Data = Secret }); NatClient?.Send(pack); } } }
static void SendHeart() { while (!IsStop) { Thread.Sleep(30000); if (NatClient.IsConnected) { //发送心跳包 var packBytes = new List <byte>() { 0x1, 0x2 }; var lenBytes = BitConverter.GetBytes(RegPack.Length).Reverse(); packBytes.AddRange(lenBytes); packBytes.AddRange(RegPack); NatClient.Send(packBytes.ToArray()); } } }
public void CloseRemouteClient() { var pack = new PackJson() { Host = PackJson.Host, UserId = PackJson.UserId }; var json = JsonHelper.Instance.Serialize(pack); var jsonBytes = Encoding.UTF8.GetBytes(json); //03 03 数据长度(4) 正文数据(n) ---tcp连接关闭包 var sendBytes = new List <byte>() { 0x3, 0x3 }; sendBytes.AddRange(BitConverter.GetBytes(jsonBytes.Length).Reverse()); sendBytes.AddRange(jsonBytes); //转发给服务器 NatClient.Send(sendBytes.ToArray()); }
/// <summary> /// 处理请求 /// </summary> /// <param name="e"></param> static void HandleRequest(PackageEventArgs <NatPackageInfo> e) { Task.Run(() => { try { var packJson = JsonHelper.Instance.Deserialize <PackJson>(e.Package.BodyRaw); var headers = packJson.Headers; var contentType = headers.ContainsKey("Content-Type") ? headers["Content-Type"] : null; var data = packJson.Content == null ? "" : Encoding.UTF8.GetString(packJson.Content); if (!string.IsNullOrEmpty(contentType)) { var index = contentType.IndexOf(";"); if (index > 0) { //去掉; charset=utf-8 contentType = contentType.Substring(0, index); } } var map = MapList.Find(c => c.remote == packJson.Host); if (map == null) { HandleLog.WriteLine($"映射不存在,外网访问地址:{packJson.Host}"); return; } var res = HttpHelper.Request(packJson.Method, $"{map.protocol}://{map.local}{packJson.Route}", data, headers: headers, contentType: contentType); if (res == null) { HandleLog.WriteLine("服务器返回NULL"); return; } using (res) { using var stream = res.Content.ReadAsStreamAsync().Result; var result = DataHelper.StreamToBytes(stream); var rawResult = Encoding.UTF8.GetString(result); StringBuilder resp = new StringBuilder(); resp.Append($"{map.protocol.ToUpper()}/{res.Version} {(int)res.StatusCode} {res.StatusCode.ToString()}\r\n"); foreach (var item in res.Headers) { if (item.Key != "Transfer-Encoding") { resp.Append($"{item.Key}: {string.Join(";", item.Value)}\r\n"); } } foreach (var item in res.Content.Headers) { resp.Append($"{item.Key}: {string.Join(";", item.Value)}\r\n"); } if (packJson.Method.ToUpper() == "OPTIONS") { resp.Append("Access-Control-Allow-Credentials: true\r\n"); if (packJson.Headers.ContainsKey("Access-Control-Request-Headers")) { resp.Append($"Access-Control-Allow-Headers: {packJson.Headers["Access-Control-Request-Headers"]}\r\n"); } resp.Append("Access-Control-Allow-Methods: *\r\n"); resp.Append($"Access-Control-Allow-Origin: {packJson.Headers["Origin"]}\r\n"); } if (!res.Content.Headers.Contains("Content-Length")) { resp.Append($"Content-Length: {result.Length}\r\n"); } resp.Append($"Date: {DateTime.Now}\r\n"); resp.Append("Connection:close\r\n\r\n"); var response = Encoding.UTF8.GetBytes(resp.ToString()).ToList(); response.AddRange(result); //先gzip压缩 再转为16进制字符串 var body = DataHelper.Compress(response.ToArray()); var pack = new PackJson() { Host = packJson.Host, UserId = packJson.UserId, Content = body, ResponseInfo = $"{map.name} {packJson.Method} {packJson.Route} {(int)res.StatusCode} {res.StatusCode.ToString()}" }; var json = JsonHelper.Instance.Serialize(pack); var jsonBytes = Encoding.UTF8.GetBytes(json); //请求头 01 03 长度(4) var sendBytes = new List <byte>() { 0x1, 0x3 }; sendBytes.AddRange(BitConverter.GetBytes(jsonBytes.Length).Reverse()); sendBytes.AddRange(jsonBytes); NatClient.Send(sendBytes.ToArray()); HandleLog.WriteLine(pack.ResponseInfo); } } catch (Exception ex) { HandleLog.WriteLine($"处理请求异常:{ex}"); } }); }
public static async void ProcessData(NatClient natClient, NatPackageInfo packageInfo) { try { switch (packageInfo.Body.Action) { case (byte)HttpAction.Request: { var httpModel = packageInfo.Body.Data.FromJson <HttpModel>(); var map = natClient.Client.MapList.Find(c => c.remote_endpoint == httpModel.Host || (c.remote == httpModel.Host && c.remote_port == 80)); if (map == null) { HandleLog.WriteLine($"映射不存在,外网访问地址:{httpModel.Host}"); return; } using HttpRequestMessage httpRequest = new HttpRequestMessage() { Method = new HttpMethod(httpModel.Method), RequestUri = new Uri($"{map.protocol}://{map.local_endpoint}{httpModel.Path}") }; HandleLog.WriteLine($"{map.name} {httpModel.Method} {httpRequest.RequestUri.AbsoluteUri} {httpModel.Headers.ToJson()}{Environment.NewLine}"); string bodyStr = string.Empty; if (httpRequest.Method != HttpMethod.Get && httpModel.Content?.Length > 0) { var body = DataHelper.Decompress(httpModel.Content); //解压 bodyStr = body.ToUTF8String(); httpRequest.Content = new StringContent(bodyStr, Encoding.UTF8, httpModel.ContentType.Split(";")[0]); } HandleLog.WriteLine($"{map.name} {httpModel.Method} {httpRequest.RequestUri.AbsoluteUri}{Environment.NewLine}【Header】{httpModel.Headers.ToJson()}{$"{Environment.NewLine}【Body】{bodyStr}".If(httpModel.Content?.Length < 1024)}{Environment.NewLine}"); using HttpClient _httpClient = new HttpClient(); //替换Host 不然400 Bad Request httpModel.Headers["Host"] = map.local_endpoint; foreach (var item in httpModel.Headers) { if (!item.Key.EqualsWhithNoCase("Content-Type")) { if (!httpRequest.Content?.Headers.TryAddWithoutValidation(item.Key, item.Value) ?? true) { _httpClient.DefaultRequestHeaders.TryAddWithoutValidation(item.Key, item.Value); } } } if (map.protocol == "https") { ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; } var response = await _httpClient.SendAsync(httpRequest); //回传给服务器 httpModel.HttpVersion = $"{map.protocol.ToUpper()}/{response.Version.ToString()}"; httpModel.StatusCode = (int)response.StatusCode; httpModel.StatusMessage = response.StatusCode.ToString(); httpModel.Local = map.local_endpoint; httpModel.Headers = response.Headers.ToDictionary(); httpModel.ResponseTime = DateTime.Now; foreach (var item in response.Content.Headers) { if (item.Key.EqualsWhithNoCase("Content-Type")) { httpModel.ContentType = string.Join(";", item.Value); } else { if (item.Key.EqualsWhithNoCase("Content-Length")) { continue; } httpModel.Headers.Add(item.Key, string.Join(";", item.Value)); } } httpModel.Headers.Remove("Transfer-Encoding"); //response收到的是完整的 这个响应头要去掉 不然浏览器解析出错 var returnContent = DataHelper.StreamToBytes(response.Content.ReadAsStreamAsync().Result); if (returnContent.Length > 0) { httpModel.Content = DataHelper.Compress(returnContent); } var pack = PackHelper.CreatePack(new JsonData() { Type = (int)JsonType.HTTP, Action = (int)HttpAction.Response, Data = httpModel.ToJson() }); natClient?.Send(pack); HandleLog.WriteLine($"{map.name} {httpModel.Method} {httpRequest.RequestUri.AbsoluteUri}{$"{returnContent.ToUTF8String()}".If(returnContent.Length < 1024)} {httpModel.StatusCode} {httpModel.StatusMessage} {Math.Round(returnContent.Length * 1.00 / 1024, 1)}KB{Environment.NewLine}"); break; } } } catch (Exception ex) { HandleLog.WriteLine($"处理请求异常:{ex}"); var pack = PackHelper.CreatePack(new JsonData() { Type = (int)JsonType.HTTP, Action = (int)HttpAction.Response, Data = new HttpModel() { StatusCode = (int)HttpStatusCode.BadRequest, ContentType = "text/html", Content = DataHelper.Compress(Encoding.UTF8.GetBytes($"server error")) }.ToJson() }); natClient?.Send(pack); } }