示例#1
0
        /// <summary>
        /// 暂不支持EPRT
        /// 1:ipV4;2 ipV6
        /// EPRT |1|132.235.1.2|6275|
        /// EPRT |2|1080::8:800:200C:417A|5282|
        ///
        /// PORT 192,168,191,11,206,97
        /// </summary>
        internal async Task <Stream> PortDataStreamAsync()
        {
            // 主动模式时,客户端必须告知服务器接收数据的端口号,PORT 命令格式为:PORT address
            //PORT 192,168,191,11,206,97
            // address参数的格式为i1、i2、i3、i4、p1、p2,其中i1、i2、i3、i4表示IP地址
            // 下面通过.字符串来组合这四个参数得到IP地址
            System.Net.Sockets.TcpListener dataListener;
            string portListener;
            string sendString = string.Empty;
            var    localip = (System.Net.IPAddress)LocalEndPoint;
            Random random = new Random();
            int    random1, random2;
            int    port;
            string ip = string.Empty;

            while (true)
            {
                // 随机生成一个端口进行数据传输
                random1 = random.Next(5, 200);
                random2 = random.Next(0, 200);
                // 生成的端口号控制>1024的随机端口
                // 下面这个运算算法只是为了得到一个大于1024的端口值
                port = random1 << 8 | random2;
                try
                {
                    dataListener = new System.Net.Sockets.TcpListener(localip, port);
                    dataListener.Start();
                }
                catch
                {
                    continue;
                }
                ip           = localip.ToString().Replace('.', ',');
                portListener = string.Format("{0},{1},{2}", ip, random1, random2);
                // 必须把端口号IP地址告诉客户端,客户端接收到响应命令后,
                // 再通过新的端口连接服务器的端口P,然后进行文件数据传输
                break;
            }
            var pasvResult = await ControlStream.SendCommandAsync(new FtpCommandEnvelope()
            {
                FtpCommand = FtpCommand.PORT,
                Data       = portListener
            });

            return(await ControlStream.AcceptDataStreamAsync(dataListener));
        }