static public void CloseSocket(this Socket socket) { try { //socket.Close(); //socket.Disconnect(false); socket.Dispose(); } catch (Exception x) { TcpMapService.OnError(x); } }
internal void Stop() { _cts_wait_upgrade?.Cancel(); if (_socket != null) { try { _socket.CloseSocket(); } catch (Exception x) { TcpMapService.OnError(x); } } }
static async Task CopyToAsync(Socket src, Socket dst) { try { byte[] buffer = new byte[65536]; while (true) { var rc = await src.ReceiveAsync(buffer, SocketFlags.None); if (rc == 0) { return; } var sc = await dst.SendAsync(new ArraySegment <byte>(buffer, 0, rc), SocketFlags.None); Debug.Assert(rc == sc); } } catch (Exception x) { TcpMapService.OnError(x); } }
public void OnError(Exception x) { this.Error = x; TcpMapService.OnError(x); }
async Task WorkAsync() { IsStarted = true; IsConnected = false; //LogMessage("ClientSession WorkAsync start"); int connectedTimes = 0; try { int againTimeout = 125; StartAgain: _sock_server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _sock_server.InitTcp(); _cts_connect = new CancellationTokenSource(); try { await _sock_server.ConnectAsync(Client.ServerHost, 6022); //LogMessage("connected to 6022"); } catch (Exception x) { OnError(x); _sock_server.CloseSocket(); _sock_server = null; _cts_connect = new CancellationTokenSource(); if (!IsStarted) { return; } if (againTimeout < 4) { againTimeout = againTimeout * 2; } if (await _cts_connect.Token.WaitForSignalSettedAsync(againTimeout)) { return; } goto StartAgain; } try { bool supportEncrypt = false; byte[] clientKeyIV; { CommandMessage connmsg = new CommandMessage(); connmsg.Name = "SessionConnect"; List <string> arglist = new List <string>(); arglist.Add(this.Client.License.Key); arglist.Add(this.Client.ServerPort.ToString()); byte[] encryptedKeyIV, sourceHash; Client.License.GenerateSecureKeyAndHash(out clientKeyIV, out encryptedKeyIV, out sourceHash); arglist.Add(Convert.ToBase64String(encryptedKeyIV)); arglist.Add(Convert.ToBase64String(sourceHash)); arglist.Add(supportEncrypt ? "1" : "0"); arglist.Add(SessionId); //sessionid at [5] connmsg.Args = arglist.ToArray(); await _sock_server.SendAsync(connmsg.Pack(), SocketFlags.None); //LogMessage("wait for conn msg"); connmsg = await CommandMessage.ReadFromSocketAsync(_sock_server); if (connmsg == null) { TcpMapService.LogMessage("no message ? Connected:" + _sock_server.Connected); return; } //LogMessage("connmsg : " + connmsg.Name + " : " + string.Join(",", connmsg.Args)); if (connmsg.Name != "ConnectOK") { IsStarted = false; //don't go until start it again. throw new Exception(connmsg.Name + " : " + string.Join(",", connmsg.Args)); } if (connmsg.Args[1] == "0") { supportEncrypt = false; } } IsConnected = true; connectedTimes++; //LogMessage("ConnectOK #" + connectedTimes); if (supportEncrypt) { Client.License.OverrideStream(_sock_server.CreateStream(), clientKeyIV, out _sread, out _swrite); } else { _sread = _swrite = _sock_server.CreateStream(); } if (string.IsNullOrEmpty(SessionId)) { //wait for Upgrade while (SessionId == null) { CommandMessage msg; var cts = new CancellationTokenSource(); _ = Task.Run(async delegate { if (await cts.Token.WaitForSignalSettedAsync(16000)) { return; } await _swrite.WriteAsync(new CommandMessage("_ping_", "forread").Pack()); }); try { msg = await CommandMessage.ReadFromStreamAsync(_sread); } finally { cts.Cancel(); } if (msg == null) { throw (new SocketException(995)); } switch (msg.Name) { case "UpgradeSession": try { _sock_local = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _sock_local.InitTcp(); await _sock_local.ConnectWithTimeoutAsync(Client.ClientHost, Client.ClientPort, 12000); } catch (Exception x) { TcpMapService.OnError(x); await _swrite.WriteAsync(new CommandMessage("UpgradeSessionResult", "Failed").Pack()); continue; } SessionId = msg.Args[0]; if (_cts_upgrade != null) { _cts_upgrade.Cancel(); } await _swrite.WriteAsync(new CommandMessage("UpgradeSessionResult", "OK").Pack()); break; case "_ping_": await _swrite.WriteAsync(new CommandMessage("_ping_result_").Pack()); break; case "_ping_result_": break; default: LogMessage("Error: 1 Ignore message " + msg); break; } } } await WorkAsync(_sock_local.CreateStream()); } catch (Exception x) { OnError(x); } } catch (SocketException) { } catch (Exception x) { OnError(x); } IsStarted = false; IsConnected = false; _sock_server?.CloseSocket(); _sock_local?.CloseSocket(); _workend = true; }
static public async Task ForwardToAndWorkAsync(this Socket socket, string ipaddr, int port) { Socket target = null; bool funcexited = false; try { target = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); target.InitTcp(); { CancellationTokenSource cts_connect_wait = new CancellationTokenSource(); _ = Task.Run(async delegate { if (!await cts_connect_wait.Token.WaitForSignalSettedAsync(5000)) { target.CloseSocket(); } }); await target.ConnectAsync(ipaddr, port); cts_connect_wait.Cancel(); } async Task CopyToAsync(Socket src, Socket dst) { try { byte[] buffer = new byte[65536]; while (true) { var rc = await src.ReceiveAsync(buffer, SocketFlags.None); if (rc == 0) { return; } var sc = await dst.SendAsync(new ArraySegment <byte>(buffer, 0, rc), SocketFlags.None); Debug.Assert(rc == sc); } } catch (Exception x) { TcpMapService.OnError(x); } } var t1 = Task.Run(async delegate { await CopyToAsync(socket, target); }); var t2 = Task.Run(async delegate { await CopyToAsync(target, socket); }); await Task.WhenAny(t1, t2); } catch (Exception x) { TcpMapService.OnError(x); socket.CloseSocket(); target?.CloseSocket(); } finally { funcexited = true; } }