Java 如何在我的FTP服务器中实现对EPSV(ALL)命令的响应?

Java 如何在我的FTP服务器中实现对EPSV(ALL)命令的响应?,java,sockets,ftp,Java,Sockets,Ftp,我正试图通过Wi-Fi在本地网络上用Java设置FTP服务器。我一直在处理epsvall命令。作为客户端,我在iPhone上使用VLC播放器。当我尝试播放.mp4文件时,它正在向服务器发送EPSV ALL。服务器对此行的响应: “229进入扩展被动模式(| | |“+自由数据端口+”)” 服务器在freeDataPort上创建serverSocket,侦听收入连接,但什么也没发生 我尝试了连接到FileZilla服务器的open movie-它可以工作。另外,我不明白为什么客户端在执行此命令(

我正试图通过Wi-Fi在本地网络上用Java设置FTP服务器。我一直在处理
epsvall
命令。作为客户端,我在iPhone上使用VLC播放器。当我尝试播放.mp4文件时,它正在向服务器发送
EPSV ALL
。服务器对此行的响应:

“229进入扩展被动模式(| | |“+自由数据端口+”)”
服务器在
freeDataPort
上创建
serverSocket
,侦听收入连接,但什么也没发生

我尝试了连接到FileZilla服务器的open movie-它可以工作。另外,我不明白为什么客户端在执行此命令(
EPSV
)后尝试建立第二个连接(请求用户并再次传递的连接),而
PASV
命令创建数据连接并执行简单的数据传输,如对
列表的响应,在第一个连接中处理

这是我使用的
EPSV
的处理程序:

private void handleEpsv() {
    sendMsgToClient("229 Entering Extended Passive Mode (|||" + freeDataPort + "|)");
    try {
        dataSocket = new ServerSocket(freeDataPort);
        System.out.println("waiting for connect... port: " + freeDataPort);
        dataConnection = dataSocket.accept();
        dataOutWriter = new PrintWriter(dataConnection.getOutputStream(), true);
    } catch (IOException e)
    {
        debugOutput("Could not create data connection.");
        e.printStackTrace();
    }
}
这就是上次的结果:

FTP服务器已开始侦听端口21
{/192.168.0.105=数据列表中的INITIALThread-0线程:0}
已收到新连接。工人被创建。
从初始线程开始
线程0-发送到客户端:220欢迎使用FTP服务器
来自初始线程的用户a
线程-0-发送到客户端:331用户名好的,需要密码
从初始线程传递一个
线程0-发送到客户端:230用户成功登录
从初始线程开始的系统
线程-0-发送到客户端:215 UNIX类型:L8
从初始螺纹开始的PWD
线程-0-发送到客户端:257“/”
从初始螺纹开始的I型
线程-0-发送到客户端:200确定
CWD//来自初始线程
线程-0-发送到客户端:250 CWD成功。/是当前目录吗
来自初始线程的PASV
线程-0-发送到客户端:227进入被动模式(192168,0199,7232)
正在等待连接。。。港口:2024年
数据连接-被动模式-已建立
来自初始线程的列表
线程0-发送到客户端:125打开文件列表的ASCII模式数据连接。
从初始线程开始
线程-0-发送到客户端:226传输完成。
{/192.168.0.105=数据列表中的INITIALThread-0线程:1}
已收到新连接。工人被创建。
线程1-发送到客户端:220欢迎使用FTP服务器
壮举
线程1-发送到客户端:211功能:
线程1-发送到客户端:MDTM
线程1-发送到客户端:REST流
线程1-发送到客户端:大小
线程1-发送到客户端:MLST类型*;大小*;修改*;
线程1-发送到客户端:MLSD
线程1-发送到客户端:UTF8
线程1-发送到客户端:CLNT
线程1-发送到客户端:MFMT
线程1-发送到客户端:EPSV
线程1-发送到客户端:EPRT
线程1-发送到客户端:211结束
用户a
线程1-发送到客户端:331用户名好的,需要密码
通过
线程1-发送到客户端:230用户成功登录
EPSV ALL
线程1-发送到客户端:229进入扩展被动模式(| | | | 2025 |)
由Thread-1线程数据类型使用
正在等待连接。。。港口:2025年

EPSV ALL
不是
EPSV
<代码>EPSV ALL
具有特殊含义。客户端使用它来表示它将只使用
EPSV
,而不是
PASV
端口
EPRT
。您应该只对它做出
200ok
之类的响应。你应该读书

实际上,我从未见过任何FTP客户端使用此命令。大多数服务器会忽略它或不正确地处理它。VLC无法与服务器通信的原因可能是,除了响应不正确外,您还阻止了控件连接,等待传入的数据传输。VLC正在发送更多命令并超时等待服务器响应(因此它可能会通过打开新连接重试)

这是到FileZilla FTP服务器的VLC连接的副本。请注意,FileZilla还错误地处理了
EPSV ALL
,通过
229进入扩展被动模式进行响应。但它不会阻止控制连接并正确处理以下命令(包括稍后的
EPSV

230已登录
EPSV ALL
229进入扩展被动模式(| | | 65079 |)
第一类
200类型设置为I
大小视频.avi
213 119035510
EPSV
229进入扩展被动模式(| | | 63465 |)
第一类
200类型设置为I
RETR video.avi
150打开从“/video.avi”服务器下载文件的数据通道
...


实际上,即使该命令是正常的
EPSV
,您也不应该阻止控制连接,因为客户端将发送进一步的命令,特别是
RETR
(或
STOR
LIST
MLSD
)。

成功了,谢谢!事实证明,如果你想获得视频流,VLC player希望你创建三个不同的线程,我阻止了第二个线程。@RomanFrolov在旁注中说,当响应PASV或EPSV进行实际传输时,在侦听端口实际打开并首先侦听之前,不要向客户端发送回复。如果端口无法打开,请改为发送失败回复。您的
handleEpsv()
没有执行这两项操作。一旦客户端收到一个成功的回复,它就会尝试连接,如果您还没有打开端口,连接就会失败