private void ListenPortMapPortWithServerName(PortMapItem item)
        {
            TcpListener listener = new TcpListener(string.IsNullOrEmpty(item.LocalAddress) ? IPAddress.Any : IPAddress.Parse(item.LocalAddress), item.LocalPort);

            try
            {
                listener.Start();
            }
            catch (SocketException ex)
            {
                LogUtils.Error($"端口映射失败:{item.LocalPort}->{item.RemoteAddress}:{item.RemotePort}{Environment.NewLine}{ex.Message}");
            }
            ListenerList.Add(listener);
            LogUtils.Show($"端口映射成功:{item.LocalPort}->{item.RemoteAddress}:{item.RemotePort}");
            Global.TaskFactory.StartNew(() =>
            {
                while (true)
                {
                    Socket socket = listener.AcceptSocket();
                    //获取目标tcp
                    if (Global.P2PServerTcp != null && Global.P2PServerTcp.Connected)
                    {
                        Global.TaskFactory.StartNew(() =>
                        {
                            P2PTcpClient tcpClient = new P2PTcpClient(socket);
                            //加入待连接集合
                            Global.WaiteConnetctTcp.Add(tcpClient.Token, tcpClient);
                            //发送p2p申请
                            Send_0x0201_Apply packet = new Send_0x0201_Apply(tcpClient.Token, item.RemoteAddress, item.RemotePort);
                            LogUtils.Info($"正在建立内网穿透(3端)通道 token:{tcpClient.Token} client:{item.RemoteAddress} port:{item.RemotePort}");
                            try
                            {
                                Global.P2PServerTcp.Client.Send(packet.PackData());
                            }
                            finally
                            {
                                //如果5秒后没有匹配成功,则关闭连接
                                Thread.Sleep(Global.P2PTimeout);
                                if (Global.WaiteConnetctTcp.ContainsKey(tcpClient.Token))
                                {
                                    LogUtils.Warning($"内网穿透失败:token:{tcpClient.Token} {item.LocalPort}->{item.RemoteAddress}:{item.RemotePort} {Global.P2PTimeout}秒无响应,已超时.");
                                    Global.WaiteConnetctTcp[tcpClient.Token].Close();
                                    Global.WaiteConnetctTcp.Remove(tcpClient.Token);
                                }
                            }
                        });
                    }
                    else
                    {
                        LogUtils.Warning($"内网穿透失败:未连接到服务器!");
                        socket.Close();
                    }
                }
            });
        }
Exemple #2
0
 private void ListenPortMapPortWithServerName(PortMapItem item)
 {
     try
     {
         TcpListener listener = new TcpListener(string.IsNullOrEmpty(item.LocalAddress) ? IPAddress.Any : IPAddress.Parse(item.LocalAddress), item.LocalPort);
         listener.Start();
         ListenerList.Add(listener);
         LogUtils.Show($"【成功】端口映射:{item.LocalPort}->{item.RemoteAddress}:{item.RemotePort}");
         Global.TaskFactory.StartNew(() =>
         {
             while (true)
             {
                 Socket socket          = listener.AcceptSocket();
                 P2PTcpClient tcpClient = new P2PTcpClient(socket);
                 Global.TaskFactory.StartNew(() =>
                 {
                     string token = tcpClient.Token;
                     //获取目标tcp
                     if (Global.P2PServerTcp != null && Global.P2PServerTcp.Connected)
                     {
                         //加入待连接集合
                         Global.WaiteConnetctTcp.Add(token, tcpClient);
                         //发送p2p申请
                         Send_0x0201_Apply packet = new Send_0x0201_Apply(token, item.RemoteAddress, item.RemotePort);
                         Global.P2PServerTcp.Client.Send(packet.PackData());
                         //LogUtils.Debug("P2P第一步:向服务器发送申请.");
                         Global.TaskFactory.StartNew(() =>
                         {
                             Thread.Sleep(Global.P2PTimeout);
                             //如果5秒后没有匹配成功,则关闭连接
                             if (Global.WaiteConnetctTcp.ContainsKey(token))
                             {
                                 LogUtils.Warning($"【失败】内网穿透:{Global.P2PTimeout}秒无响应,已超时.");
                                 Global.WaiteConnetctTcp[token].Close();
                                 Global.WaiteConnetctTcp.Remove(token);
                             }
                         });
                     }
                     else
                     {
                         LogUtils.Warning($"【失败】内网穿透:未连接服务器!");
                         tcpClient.Close();
                     }
                 });
             }
         });
     }
     catch (Exception ex)
     {
         LogUtils.Error($"【失败】端口映射:{item.LocalPort}->{item.RemoteAddress}:{item.RemotePort}{Environment.NewLine}{ex.ToString()}");
     }
 }
        /// <summary>
        /// 端口映射监听端口的新tcp回调方法
        /// </summary>
        /// <param name="ar"></param>
        public void AcceptSocket_Server(IAsyncResult ar)
        {
            ListenSt    st       = (ListenSt)ar.AsyncState;
            TcpListener listener = st.listener;
            PortMapItem item     = st.item;
            Socket      socket   = null;

            try
            {
                //获取当前接入的tcp
                socket = listener.EndAcceptSocket(ar);
            }
            catch (Exception ex)
            {
                LogUtils.Error(ex.ToString());
                return;
            }

            EasyOp.Do(() =>
            {
                listener.BeginAcceptSocket(AcceptSocket_Server, st);
            }, () =>
            {
                EasyOp.Do(() =>
                {
                    if (tcpCenter.P2PServerTcp != null && tcpCenter.P2PServerTcp.Connected)
                    {
                        P2PTcpClient tcpClient = new P2PTcpClient(socket);
                        //加入待连接集合
                        P2PResult result = new P2PResult();
                        tcpCenter.WaiteConnetctTcp.Add(tcpClient.Token, result);
                        //tcpCenter.WaiteConnetctTcp.Add(tcpClient.Token, tcpClient);
                        //发送消息给服务端,开始内网穿透
                        Send_0x0201_Apply packet = new Send_0x0201_Apply(tcpClient.Token, item.RemoteAddress, item.RemotePort, item.P2PType);
                        LogUtils.Debug(string.Format("正在建立{0}隧道 token:{1} client:{2} port:{3}", item.P2PType == 0 ? "中转模式" : "P2P模式", tcpClient.Token, item.RemoteAddress, item.RemotePort));

                        byte[] dataAr = packet.PackData();
                        EasyOp.Do(() =>
                        {
                            tcpCenter.P2PServerTcp.BeginSend(dataAr);
                        }, () =>
                        {
                            //等待指定超时时间后,判断是否连接成功

                            Monitor.Enter(result.block);
                            if (Monitor.Wait(result.block, AppConfig.P2PTimeout))
                            {
                                if (tcpCenter.WaiteConnetctTcp[tcpClient.Token].IsError)
                                {
                                    LogUtils.Debug(tcpCenter.WaiteConnetctTcp[tcpClient.Token].ErrorMsg);
                                    tcpClient.SafeClose();
                                }
                                else
                                {
                                    P2PTcpClient destTcp = tcpCenter.WaiteConnetctTcp[tcpClient.Token].Tcp;
                                    tcpClient.IsAuth     = destTcp.IsAuth = true;
                                    destTcp.ToClient     = tcpClient;
                                    tcpClient.ToClient   = destTcp;
                                    if (item.P2PType == 0)
                                    {
                                        Global_Func.ListenTcp <Packet_0x0202>(tcpClient);
                                        LogUtils.Debug($"中转模式隧道,连接成功 token:{tcpClient.Token}");
                                    }
                                    else
                                    {
                                        if (Global_Func.BindTcp(tcpClient, destTcp))
                                        {
                                            LogUtils.Debug($"P2P模式隧道,连接成功 token:{tcpClient.Token}");
                                        }
                                        else
                                        {
                                            LogUtils.Debug($"P2P模式隧道,连接失败 token:{tcpClient.Token}");
                                            EasyOp.Do(tcpClient.SafeClose);
                                            EasyOp.Do(destTcp.SafeClose);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                LogUtils.Debug($"建立隧道失败:token:{tcpClient.Token} {item.LocalPort}->{item.RemoteAddress}:{item.RemotePort} {AppConfig.P2PTimeout / 1000}秒无响应,已超时.");
                                EasyOp.Do(tcpClient.SafeClose);
                            }
                            tcpCenter.WaiteConnetctTcp.Remove(tcpClient.Token);
                            Monitor.Exit(result.block);
                            //if (tcpCenter.WaiteConnetctTcp.ContainsKey(tcpClient.Token))
                            //{
                            //    LogUtils.Debug($"建立隧道失败:token:{tcpClient.Token} {item.LocalPort}->{item.RemoteAddress}:{item.RemotePort} {AppConfig.P2PTimeout / 1000}秒无响应,已超时.");
                            //    tcpCenter.WaiteConnetctTcp[tcpClient.Token].tcp?.SafeClose();
                            //    tcpCenter.WaiteConnetctTcp.Remove(tcpClient.Token);
                            //}
                        }, ex =>
                        {
                            EasyOp.Do(tcpClient.SafeClose);
                            LogUtils.Debug($"建立隧道失败,无法连接服务器:token:{tcpClient.Token} {item.LocalPort}->{item.RemoteAddress}:{item.RemotePort}.");
                        });
                    }
                    else
                    {
                        LogUtils.Debug($"建立隧道失败:未连接到服务器!");
                        socket.Close();
                    }
                }, ex =>
                {
                    LogUtils.Debug("处理新tcp连接时发生错误:" + Environment.NewLine + ex.ToString());
                });
            }, ex =>
            {
                LogUtils.Error("监听端口发生错误:" + listener.LocalEndpoint.ToString() + Environment.NewLine + ex.ToString());
            });
        }
        /// <summary>
        /// 端口映射监听端口的新tcp回调方法
        /// </summary>
        /// <param name="ar"></param>
        public void AcceptSocket_Server(IAsyncResult ar)
        {
            ListenSt    st       = (ListenSt)ar.AsyncState;
            TcpListener listener = st.listener;
            PortMapItem item     = st.item;
            Socket      socket   = null;

            try
            {
                //获取当前接入的tcp
                socket = listener.EndAcceptSocket(ar);
            }
            catch (Exception ex)
            {
                LogUtils.Error(ex.ToString());
                return;
            }
            try
            {
                listener.BeginAcceptSocket(AcceptSocket_Server, st);
            }
            catch (Exception ex)
            {
                LogUtils.Error("监听端口发生错误:" + listener.LocalEndpoint.ToString() + Environment.NewLine + ex.ToString());
            }
            try
            {
                if (tcpCenter.P2PServerTcp != null && tcpCenter.P2PServerTcp.Connected)
                {
                    P2PTcpClient tcpClient = new P2PTcpClient(socket);
                    //加入待连接集合
                    tcpCenter.WaiteConnetctTcp.Add(tcpClient.Token, tcpClient);
                    //发送消息给服务端,开始内网穿透
                    Send_0x0201_Apply packet = new Send_0x0201_Apply(tcpClient.Token, item.RemoteAddress, item.RemotePort, item.P2PType);
                    LogUtils.Debug(string.Format("正在建立{0}隧道 token:{1} client:{2} port:{3}", item.P2PType == 0 ? "中转模式" : "P2P模式", tcpClient.Token, item.RemoteAddress, item.RemotePort));

                    byte[] dataAr = packet.PackData();
                    EasyOp.Do(() =>
                    {
                        tcpCenter.P2PServerTcp.BeginSend(dataAr);
                    }, () =>
                    {
                        //等待指定超时时间后,判断是否连接成功
                        Thread.Sleep(AppConfig.P2PTimeout);
                        if (tcpCenter.WaiteConnetctTcp.ContainsKey(tcpClient.Token))
                        {
                            LogUtils.Debug($"建立隧道失败:token:{tcpClient.Token} {item.LocalPort}->{item.RemoteAddress}:{item.RemotePort} {AppConfig.P2PTimeout / 1000}秒无响应,已超时.");
                            tcpCenter.WaiteConnetctTcp[tcpClient.Token]?.SafeClose();
                            tcpCenter.WaiteConnetctTcp.Remove(tcpClient.Token);
                        }
                    }, ex =>
                    {
                        EasyOp.Do(tcpClient.SafeClose);
                        LogUtils.Debug($"建立隧道失败,无法连接服务器:token:{tcpClient.Token} {item.LocalPort}->{item.RemoteAddress}:{item.RemotePort}.");
                    });
                }
                else
                {
                    LogUtils.Debug($"建立隧道失败:未连接到服务器!");
                    socket.Close();
                }
            }
            catch (Exception ex)
            {
                LogUtils.Debug("处理新tcp连接时发生错误:" + Environment.NewLine + ex.ToString());
            }
        }
        public bool CreateP2PConnect(PortMapItem item, Socket socket)
        {
            bool ret = false;

            if (tcpCenter.P2PServerTcp != null && tcpCenter.P2PServerTcp.Connected)
            {
                P2PTcpClient tcpClient = new P2PTcpClient(socket);
                //加入待连接集合
                P2PResult result = new P2PResult();
                tcpCenter.WaiteConnetctTcp.Add(tcpClient.Token, result);
                //tcpCenter.WaiteConnetctTcp.Add(tcpClient.Token, tcpClient);
                //发送消息给服务端,开始内网穿透
                Send_0x0201_Apply packet = new Send_0x0201_Apply(tcpClient.Token, item.RemoteAddress, item.RemotePort, item.P2PType);
                LogUtils.Debug(string.Format("正在建立{0}隧道 token:{1} client:{2} port:{3}", item.P2PType == 0 ? "中转模式" : "P2P模式", tcpClient.Token, item.RemoteAddress, item.RemotePort));

                byte[] dataAr = packet.PackData();
                EasyOp.Do(() =>
                {
                    tcpCenter.P2PServerTcp.BeginSend(dataAr);
                }, () =>
                {
                    Monitor.Enter(result.block);
                    if (Monitor.Wait(result.block, AppConfig.P2PTimeout))
                    {
                        if (tcpCenter.WaiteConnetctTcp[tcpClient.Token].IsError)
                        {
                            LogUtils.Debug(tcpCenter.WaiteConnetctTcp[tcpClient.Token].ErrorMsg);
                            //tcpClient.SafeClose();
                        }
                        else
                        {
                            P2PTcpClient destTcp = tcpCenter.WaiteConnetctTcp[tcpClient.Token].Tcp;
                            tcpClient.IsAuth     = destTcp.IsAuth = true;
                            destTcp.ToClient     = tcpClient;
                            tcpClient.ToClient   = destTcp;
                            if (item.P2PType == 0)
                            {
                                Global_Func.ListenTcp <Packet_0x0202>(tcpClient);
                                ret = true;
                                LogUtils.Debug($"中转模式隧道,连接成功 token:{tcpClient.Token}");
                            }
                            else
                            {
                                if (Global_Func.BindTcp(tcpClient, destTcp))
                                {
                                    ret = true;
                                    LogUtils.Debug($"P2P模式隧道,连接成功 token:{tcpClient.Token}");
                                }
                                else
                                {
                                    LogUtils.Debug($"P2P模式隧道,连接失败 token:{tcpClient.Token}");
                                    EasyOp.Do(destTcp.SafeClose);
                                }
                            }
                        }
                    }
                    else
                    {
                        LogUtils.Debug($"建立隧道失败:token:{tcpClient.Token} {item.LocalPort}->{item.RemoteAddress}:{item.RemotePort} {AppConfig.P2PTimeout / 1000}秒无响应,已超时.");
                    }
                    tcpCenter.WaiteConnetctTcp.Remove(tcpClient.Token);
                    Monitor.Exit(result.block);
                }, ex =>
                {
                    LogUtils.Debug($"建立隧道失败,无法连接服务器:token:{tcpClient.Token} {item.LocalPort}->{item.RemoteAddress}:{item.RemotePort}.");
                });
            }
            else
            {
                LogUtils.Debug($"建立隧道失败:未连接到服务器!");
            }
            return(ret);
        }
        private void ListenPortMapPortWithServerName(PortMapItem item)
        {
            TcpListener listener = null;

            try
            {
                listener = new TcpListener(string.IsNullOrEmpty(item.LocalAddress) ? IPAddress.Any : IPAddress.Parse(item.LocalAddress), item.LocalPort);
                listener.Start();
            }
            catch (SocketException ex)
            {
                LogUtils.Error($"端口映射失败:{item.LocalPort}->{item.RemoteAddress}:{item.RemotePort}{Environment.NewLine}{ex.Message}");
                return;
            }
            TcpCenter.Instance.ListenerList.Add($"{item.LocalAddress}:{item.LocalPort}", listener);
            LogUtils.Info($"端口映射:{item.LocalPort}->{item.RemoteAddress}:{item.RemotePort}", false);
            AppCenter.Instance.StartNewTask(() =>
            {
                while (true)
                {
                    Socket socket = null;
                    try
                    {
                        socket = listener.AcceptSocket();
                    }
                    catch
                    {
                        break;
                    }
                    //获取目标tcp
                    if (TcpCenter.Instance.P2PServerTcp != null && TcpCenter.Instance.P2PServerTcp.Connected)
                    {
                        AppCenter.Instance.StartNewTask(() =>
                        {
                            P2PTcpClient tcpClient = new P2PTcpClient(socket);
                            //加入待连接集合
                            TcpCenter.Instance.WaiteConnetctTcp.Add(tcpClient.Token, tcpClient);
                            //发送p2p申请
                            Send_0x0201_Apply packet = new Send_0x0201_Apply(tcpClient.Token, item.RemoteAddress, item.RemotePort, item.P2PType);
                            if (item.P2PType == 0)
                            {
                                LogUtils.Info($"建立内网穿透(转发模式)通道 token:{tcpClient.Token} client:{item.RemoteAddress} port:{item.RemotePort}");
                            }
                            else
                            {
                                LogUtils.Info($"建立内网穿透(P2P模式)通道 token:{tcpClient.Token} client:{item.RemoteAddress} port:{item.RemotePort}");
                            }
                            try
                            {
                                TcpCenter.Instance.P2PServerTcp.Client.Send(packet.PackData());
                            }
                            finally
                            {
                                //如果5秒后没有匹配成功,则关闭连接
                                Thread.Sleep(ConfigCenter.P2PTimeout);
                                if (TcpCenter.Instance.WaiteConnetctTcp.ContainsKey(tcpClient.Token))
                                {
                                    LogUtils.Warning($"内网穿透失败:token:{tcpClient.Token} {item.LocalPort}->{item.RemoteAddress}:{item.RemotePort} {ConfigCenter.P2PTimeout / 1000}秒无响应,已超时.");
                                    TcpCenter.Instance.WaiteConnetctTcp[tcpClient.Token].SafeClose();
                                    TcpCenter.Instance.WaiteConnetctTcp.Remove(tcpClient.Token);
                                }
                            }
                        });
                    }
                    else
                    {
                        LogUtils.Warning($"内网穿透失败:未连接到服务器!");
                        socket.Close();
                    }
                }
            });
        }