/// <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)); }