예제 #1
0
 static public void CloseSocket(this Socket socket)
 {
     try
     {
         //socket.Close();
         //socket.Disconnect(false);
         socket.Dispose();
     }
     catch (Exception x)
     {
         TcpMapService.OnError(x);
     }
 }
예제 #2
0
 internal void Stop()
 {
     _cts_wait_upgrade?.Cancel();
     if (_socket != null)
     {
         try
         {
             _socket.CloseSocket();
         }
         catch (Exception x)
         {
             TcpMapService.OnError(x);
         }
     }
 }
예제 #3
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);
                    }
                }
예제 #4
0
 public void OnError(Exception x)
 {
     this.Error = x;
     TcpMapService.OnError(x);
 }
예제 #5
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;
        }
예제 #6
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;
            }
        }