protected override async Task <CommandMessage> ReadMessageAsync()
        {
            if (this.sread == null)
            {
                await this.WaitForAttachAsync();
            }

ReadAgain:
            var msg = await CommandMessage.ReadFromStreamAsync(this.sread);

            if (msg == null || msg.Name == "data")
            {
                return(msg);
            }

            //TcpMapService.LogMessage("ServerSession:get message " + msg);

            switch (msg.Name)
            {
            case "_ping_":
                await this.swrite.WriteAsync(new CommandMessage("_ping_result_").Pack());

                break;

            case "_ping_result_":
                break;

            default:
                TcpMapService.LogMessage("Error: 6 Ignore message " + msg);
                break;
            }
            goto ReadAgain;
        }
Ejemplo n.º 2
0
        async Task SessionToStreamAsync(Stream stream)
        {
            try
            {
                while (true)
                {
                    //TcpMapService.LogMessage(this.GetType().Name + " ReadMessageAsync");
                    var msg = await ReadMessageAsync();

                    //TcpMapService.LogMessage(this.GetType().Name + " ReadMessageAsync DONE : " + msg);
                    if (msg == null)
                    {
                        return;
                    }
                    if (msg.Name == "data")
                    {
                        await stream.WriteAsync(msg.Data);
                    }
                    else
                    {
                        TcpMapService.LogMessage("Warning:this message shall not pass to BaseSession : " + msg);
                    }
                    //TcpMapService.LogMessage(this.GetType().Name + " WriteAsync DONE : " + msg);
                }
            }
            catch (Exception x)
            {
                //TcpMapService.OnError(x);
            }
            finally
            {
                //TcpMapService.LogMessage(this.GetType().Name + " EXITING SessionToStreamAsync");
            }
        }
Ejemplo n.º 3
0
        protected override async Task <CommandMessage> ReadMessageAsync()
        {
ReadAgain:

            CommandMessage msg;
            CancellationTokenSource cts = null;

            if (DateTime.Now - _lastwritetime > TimeSpan.FromMilliseconds(12000))
            {
                _lastwritetime = DateTime.Now;
                await _swrite.WriteAsync(new CommandMessage("_ping_", "forwrite").Pack());
            }
            else
            {
                cts = new CancellationTokenSource();
                _   = Task.Run(async delegate
                {
                    if (await cts.Token.WaitForSignalSettedAsync(16000))
                    {
                        return;
                    }
                    _lastwritetime = DateTime.Now;
                    await _swrite.WriteAsync(new CommandMessage("_ping_", "forread").Pack());
                });
            }
            try
            {
                msg = await CommandMessage.ReadFromStreamAsync(_sread);
            }
            finally
            {
                if (cts != null)
                {
                    cts.Cancel();
                }
            }

            if (msg == null || msg.Name == "data")
            {
                return(msg);
            }

            //TcpMapService.LogMessage("ClientSession:get message " + msg);

            switch (msg.Name)
            {
            case "_ping_":
                await _swrite.WriteAsync(new CommandMessage("_ping_result_").Pack());

                break;

            case "_ping_result_":
                break;

            default:
                TcpMapService.LogMessage("Error: 2 Ignore message " + msg);
                break;
            }
            goto ReadAgain;
        }
Ejemplo n.º 4
0
 public void LogMessage(string msg)
 {
     this.logMessages.Enqueue(msg);
     while (this.logMessages.Count > 200)
     {
         this.logMessages.TryDequeue(out _);
     }
     TcpMapService.LogMessage(msg);
 }
Ejemplo n.º 5
0
 static public void CloseSocket(this Socket socket)
 {
     try
     {
         //socket.Close();
         //socket.Disconnect(false);
         socket.Dispose();
     }
     catch (Exception x)
     {
         TcpMapService.OnError(x);
     }
 }
Ejemplo n.º 6
0
 internal void Stop()
 {
     _cts_wait_upgrade?.Cancel();
     if (_socket != null)
     {
         try
         {
             _socket.CloseSocket();
         }
         catch (Exception x)
         {
             TcpMapService.OnError(x);
         }
     }
 }
		protected override async Task<CommandMessage> ReadMessageAsync()
		{
			ReadAgain:

			CommandMessage msg;
			var cts = new CancellationTokenSource();
			_ = Task.Run(async delegate
			{
				if (await cts.Token.WaitForSignalSettedAsync(16000))
					return;
				try
				{
					await _swrite.WriteAsync(new CommandMessage("_ping_", "forread").Pack());
				}
				catch (Exception x)
				{
					OnError(x);
				}
			});
			try
			{
				msg = await CommandMessage.ReadFromStreamAsync(_sread);
			}
			finally
			{
				cts.Cancel();
			}

			if (msg == null || msg.Name == "data")
				return msg;

			//TcpMapService.LogMessage("ServerSession:get message " + msg);

			switch (msg.Name)
			{
				case "_ping_":
					await _swrite.WriteAsync(new CommandMessage("_ping_result_").Pack());
					break;
				case "_ping_result_":
					break;
				default:
					TcpMapService.LogMessage("Error: 3 Ignore message " + msg);
					break;
			}
			goto ReadAgain;
		}
Ejemplo n.º 8
0
        private async Task SessionToStreamAsync(Stream stream)
        {
            try
            {
                while (true)
                {
                    //TcpMapService.LogMessage(this.GetType().Name + " ReadMessageAsync");
                    var msg = await this.ReadMessageAsync();

                    if (msg == null)
                    {
                        return;
                    }

                    if (msg.Name == "data")
                    {
                        //TcpMapService.LogMessage(this.GetType().Name + " ReadMessageAsync DONE : " + msg);
                        //TcpMapService.LogMessage("Data:" + Encoding.UTF8.GetString(msg.Data.ToArray()));
                        await stream.WriteAsync(msg.Data);
                    }
                    else
                    {
                        TcpMapService.LogMessage("Warning:this message shall not pass to BaseSession : " + msg);
                    }
                    //TcpMapService.LogMessage(this.GetType().Name + " WriteAsync DONE : " + msg);
                }
            }
            catch (ObjectDisposedException)
            {
                //no log
            }
            catch (Exception)
            {
                //TcpMapService.OnError(x);
            }
            finally
            {
                //TcpMapService.LogMessage(this.GetType().Name + " EXITING SessionToStreamAsync");
            }
        }
Ejemplo n.º 9
0
                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);
                    }
                }
Ejemplo n.º 10
0
        private async Task WorkAsync()
        {
            this.IsConnected = false;
            this.LogMessage("ClientWorker WorkAsync start");
            int connectedTimes = 0;

            try
            {
                int againTimeout = 125;
StartAgain:

                this.socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                this.socket.InitTcp();
                this.cts_connect = new CancellationTokenSource();
                try
                {
                    await this.socket.ConnectAsync(this.Client.ServerHost, 6022);

                    this.LogMessage("connected to 6022");
                }
                catch (Exception x)
                {
                    this.OnError(x);
                    this.socket.CloseSocket();
                    this.socket      = null;
                    this.cts_connect = new CancellationTokenSource();
                    if (!this.IsStarted)
                    {
                        return;
                    }

                    if (againTimeout < 4)
                    {
                        againTimeout *= 2;
                    }

                    if (await this.cts_connect.Token.WaitForSignalSettedAsync(againTimeout))
                    {
                        return;
                    }

                    goto StartAgain;
                }

                try
                {
                    bool   supportEncrypt = this.Client.UseEncrypt;
                    byte[] clientKeyIV;

                    {
                        CommandMessage connmsg = new CommandMessage
                        {
                            Name = "ClientConnect"
                        };
                        List <string> arglist = new List <string>
                        {
                            this.Client.License.Key,
                            this.Client.ServerPort.ToString()
                        };
                        this.Client.License.GenerateSecureKeyAndHash(out clientKeyIV, out byte[] encryptedKeyIV, out byte[] sourceHash);
                        arglist.Add(Convert.ToBase64String(encryptedKeyIV));
                        arglist.Add(Convert.ToBase64String(sourceHash));
                        arglist.Add(supportEncrypt ? "1" : "0");
                        connmsg.Args = arglist.ToArray();

                        await this.socket.SendAsync(connmsg.Pack(), SocketFlags.None);

                        //LogMessage("wait for conn msg");

                        connmsg = await CommandMessage.ReadFromSocketAsync(this.socket);

                        if (connmsg == null)
                        {
                            TcpMapService.LogMessage("no message ? Connected:" + this.socket.Connected);
                            return;
                        }

                        this.LogMessage("connmsg : " + connmsg.Name + " : " + string.Join(",", connmsg.Args));

                        if (connmsg.Name != "ConnectOK")
                        {
                            this.IsStarted = false;//don't go until start it again.
                            throw new Exception(connmsg.Name + " : " + string.Join(",", connmsg.Args));
                        }

                        if (supportEncrypt && connmsg.Args[1] == "0")
                        {
                            supportEncrypt = false; this.LogMessage("Warning:server don't support encryption.");
                        }
                    }

                    this.IsConnected = true;

                    connectedTimes++;
                    this.LogMessage("ConnectOK #" + connectedTimes);

                    if (supportEncrypt)
                    {
                        this.Client.License.OverrideStream(this.socket.CreateStream(), clientKeyIV, out this.sread, out this.swrite);
                    }
                    else
                    {
                        this.sread = this.swrite = this.socket.CreateStream();
                    }

                    for (int i = 0; i < Math.Min(5, this.Client.PreSessionCount); i++)//TODO:const of 5
                    {
                        _ = Task.Run(this.ProvidePreSessionAsync);
                    }

                    _ = Task.Run(this.MaintainSessionsAsync);

                    if (this.Client.RouterClientPort > 0)
                    {
                        _ = this.swrite.WriteAsync(new CommandMessage("SetOption", "RouterClientPort", this.Client.RouterClientPort.ToString()).Pack());
                    }

                    byte[] readbuff = new byte[TcpMapService.defaultBufferSize];
                    while (this.IsStarted)
                    {
                        CommandMessage msg;
                        var            cts = new CancellationTokenSource();
                        _ = Task.Run(async delegate
                        {
                            if (await cts.Token.WaitForSignalSettedAsync(16000))
                            {
                                return;
                            }

                            try
                            {
                                await this.swrite.WriteAsync(new CommandMessage("_ping_", "forread").Pack());
                            }
                            catch (Exception x)
                            {
                                this.OnError(x);
                            }
                        });
                        try
                        {
                            msg = await CommandMessage.ReadFromStreamAsync(this.sread);
                        }
                        finally
                        {
                            cts.Cancel();
                        }

                        if (msg == null)
                        {
                            TcpMapService.LogMessage("no message ? Connected:" + this.socket.Connected);
                            return;
                        }

                        //this.LogMessage("TcpMapClientWorker get msg " + msg);

                        switch (msg.Name)
                        {
                        case "StartSession":
                            Task.Run(async delegate
                            {
                                try
                                {
                                    await this.DoStartSessionAsync(msg);
                                }
                                catch (Exception x)
                                {
                                    this.OnError(x);
                                }
                            }).ToString();
                            break;

                        case "CloseSession":
                            Task.Run(async delegate
                            {
                                try
                                {
                                    await this.DoCloseSessionAsync(msg);
                                }
                                catch (Exception x)
                                {
                                    this.OnError(x);
                                }
                            }).ToString();
                            break;

                        case "CreateUDPNat":
                            Task.Run(async delegate
                            {
                                try
                                {
                                    await this.DoCreateUDPNatAsync(msg);
                                }
                                catch (Exception x)
                                {
                                    this.OnError(x);
                                }
                            }).ToString();
                            break;

                        case "_ping_":
                            await this.swrite.WriteAsync(new CommandMessage("_ping_result_").Pack());

                            break;

                        case "_ping_result_":
                            break;

                        default:
                            this.LogMessage("Error: 4 Ignore message " + msg);
                            break;
                        }
                    }
                }
                catch (SocketException)
                {
                    //no log
                }
                catch (Exception x)
                {
                    this.OnError(x);
                }
                if (this.IsStarted)
                {
                    this.socket.CloseSocket();//logic failed..
                    againTimeout = 125;
                    goto StartAgain;
                }
            }
            catch (Exception x)
            {
                this.OnError(x);
            }

            this.IsStarted   = false;
            this.IsConnected = false;

            if (this.socket != null)
            {
                try
                {
                    this.socket.CloseSocket();
                }
                catch (Exception x)
                {
                    this.OnError(x);
                }
                this.socket = null;
            }
        }
Ejemplo n.º 11
0
 public void OnError(Exception x)
 {
     this.Error = x;
     TcpMapService.OnError(x);
 }
Ejemplo n.º 12
0
        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;
        }
Ejemplo n.º 13
0
        async Task WorkAsync(CommandMessage connmsg)
        {
            if (connmsg.Name == "SessionConnect")
            {
                _is_client  = false;
                _is_session = true;
            }


            byte[] clientKeyIV;

            _worker = TcpMapService.FindServerWorkerByKey(connmsg.Args[0], int.Parse(connmsg.Args[1]));

            string failedreason = null;

            if (_worker == null)
            {
                failedreason = "NotFound";
            }
            else if (!_worker.Server.IsValidated)
            {
                failedreason = "NotValidated";
            }
            else if (_worker.Server.IsDisabled)
            {
                failedreason = "NotEnabled";
            }

            if (_worker == null || !string.IsNullOrEmpty(failedreason))
            {
                var failedmsg = new CommandMessage("ConnectFailed", failedreason);
                await _socket.SendAsync(failedmsg.Pack(), SocketFlags.None);

                return;
            }

            bool supportEncrypt = _worker.Server.UseEncrypt;

            if (connmsg.Args[4] == "0")
            {
                supportEncrypt = false;
            }

            try
            {
                _worker.Server.License.DescriptSourceKey(Convert.FromBase64String(connmsg.Args[2]), Convert.FromBase64String(connmsg.Args[3]), out clientKeyIV);
            }
            catch (Exception x)
            {
                _worker.OnError(x);
                var failedmsg = new CommandMessage("ConnectFailed", "InvalidSecureKey");
                await _socket.SendAsync(failedmsg.Pack(), SocketFlags.None);

                return;
            }

            var successMsg = new CommandMessage("ConnectOK", "ConnectOK", supportEncrypt ? "1" : "0");
            await _socket.SendAsync(successMsg.Pack(), SocketFlags.None);

            if (supportEncrypt)
            {
                _worker.Server.License.OverrideStream(_socket.CreateStream(), clientKeyIV, out _sread, out _swrite);
            }
            else
            {
                _sread = _swrite = _socket.CreateStream();
            }

            if (_is_session)
            {
                this.SessionId = connmsg.Args[5];
                if (SessionId == null)
                {
                    _cts_wait_upgrade = new CancellationTokenSource();
                }
            }

            _worker.AddClientOrSession(this);
            try
            {
                if (_is_client)
                {
                    _ = _swrite.WriteAsync(new CommandMessage("SetOption", "ClientEndPoint", _socket.RemoteEndPoint.ToString()).Pack());

                    while (true)
                    {
                        var msg = await CommandMessage.ReadFromStreamAsync(_sread);

                        //process it...

                        if (msg == null)
                        {
                            //TcpMapService.LogMessage("no message ? Connected:" + _socket.Connected);
                            throw new SocketException(995);
                        }

                        //_worker.LogMessage("TcpMapServerClient get msg " + msg);

                        switch (msg.Name)
                        {
                        case "SetOption":
                            string optvalue = msg.Args[1];
                            switch (msg.Args[0])
                            {
                            case "RouterClientPort":
                                this.OptionRouterClientPort = int.Parse(optvalue);
                                break;

                            default:
                                _worker.LogMessage("Error:Ignore option " + msg);
                                break;
                            }
                            break;

                        case "StartSessionResult":
                        case "CloseSessionResult":
                        case "CreateUDPNatResult":
                            long reqid = long.Parse(msg.Args[0]);
                            if (reqmap.TryGetValue(reqid, out var ritem))
                            {
                                ritem.Response = msg;
                                ritem.cts.Cancel();
                            }
                            else
                            {
                                _worker.LogMessage("Request Expired : " + msg);
                            }
                            break;

                        case "_ping_":
                            this._lastPingTime = DateTime.Now;
                            await _swrite.WriteAsync(new CommandMessage("_ping_result_").Pack());

                            break;

                        case "_ping_result_":
                            break;

                        default:
                            _worker.LogMessage("Error: 5 Ignore message " + msg);
                            break;
                        }
                    }
                }
                else if (_is_session)
                {
                    if (SessionId == null)
                    {
                        _worker.LogMessage($"Warning:ServerClient*{_scid} Wait for Upgrade To Session ");

                        while (SessionId == null)
                        {
                            if (await _cts_wait_upgrade.Token.WaitForSignalSettedAsync(28000))                              //check the presession closed or not every 28 seconds
                            {
                                if (SessionId != null)
                                {
                                    break;                                      //OK, session attached.
                                }
                                throw new SocketException(995);                 //_cts_wait_upgrade Cancelled , by SessionId is not seted
                            }

                            //if (!_socket.Connected) //NEVER useful..
                            //{
                            //	_worker.LogMessage("Warning:presession exit.");
                            //	throw new SocketException(995);
                            //}

                            if (!_socket.Poll(0, SelectMode.SelectRead))                             //WORKS..
                            {
                                continue;
                            }

                            if (_socket.Available == 0)
                            {
                                _worker.LogMessage("Warning:presession exit!");
                                throw new SocketException(995);
                            }

                            //_worker.LogMessage("Warning:presession send message before upgrade ?"+_socket.Available);
                            if (!_cts_wait_upgrade.IsCancellationRequested)
                            {
                                //TODO:not locked/sync, not so safe it the presession is upgrading
                                var msg = await CommandMessage.ReadFromSocketAsync(_socket);

                                if (msg.Name == "_ping_")
                                {
                                    byte[] resp = new CommandMessage("_ping_result_").Pack();
                                    await _socket.SendAsync(resp, SocketFlags.None);
                                }
                                else
                                {
                                    _worker.LogMessage("Warning:presession unexpected msg : " + msg);
                                }
                            }
                        }

                        _worker.LogMessage($"Warning:ServerClient*{_scid} SessionId:" + SessionId);
                    }

                    int waitMapTimes = 0;
TryGetMap:

                    if (_attachedSession != null)
                    {
                        _worker.LogMessage($"ServerClient*{_scid} use attached Session : {SessionId} *{waitMapTimes}");
                        await _attachedSession.UseThisSocketAsync(_sread, _swrite);
                    }
                    else if (_worker.sessionMap.TryGetValue(SessionId, out var session))
                    {
                        _worker.LogMessage($"ServerClient*{_scid} session server ok : {SessionId} *{waitMapTimes}");
                        await session.UseThisSocketAsync(_sread, _swrite);
                    }
                    else
                    {
                        if (waitMapTimes < 5)
                        {
                            waitMapTimes++;
                            await Task.Delay(10);                            //wait sessionMap be added..

                            goto TryGetMap;
                        }

                        _worker.LogMessage($"Warning:ServerClient*{_scid} session not found : {SessionId}");
                        throw new Exception($"ServerClient*{_scid} session not found : {SessionId}");
                    }
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }
            catch (SocketException)
            {
                //no log
            }
            catch (Exception x)
            {
                _worker.OnError(x);
            }
            finally
            {
                _worker.RemoveClientOrSession(this);
            }

            _worker.LogMessage($"ServerClient*{_scid} WorkAsync END " + SessionId);
        }
Ejemplo n.º 14
0
        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;
            }
        }