我正在Java中实现TFTP(普通 FTP)协议。我有一个客户端和一个服务器,到目前为止,客户端可以请求一个文件,然后服务器向他发送该数据。
这是我遇到问题的地方 - 出于明显的测试原因,我在我的机器上同时运行客户端和服务器。但是,发送文件时,必须有两个套接字在同一个端口上侦听:
- 客户端需要监听接收到的数据包
- 服务器需要监听客户端的确认
...以及用于发送数据和确认的两个各自的套接字,也共享一个端口。
这通常发生在同一个端口上,但在不同的机器上。有没有办法解决这个问题,让客户端和服务器在同一台主机上和平地工作,没有任何丑陋的黑客攻击?通过丑陋的黑客,我的意思是:
- ACK 通信端口的预定义偏移量(例如数据端口上的 +15;这是我现在正在使用的。它有点工作,但感觉不对并且容易出错)
反复关闭和打开套接字(发送数据,关闭用于发送数据的套接字,以便客户端可以使用该端口发送他的 ACK 等);这目前也有效,但也可以通过黑客攻击。例如,这是我如何“重新打开”用于发送内容的套接字:
公共无效打开(){ 尝试 { socket = new DatagramSocket(localPortCache); } 捕捉(SocketException e){ e.printStackTrace(); } }
这是邪恶的。我的套接字最初接收动态分配的临时端口号。然后我记住该值并使用它将我的套接字“恢复”到旧端口。但是,不能保证该端口仍然可用。通常是这样,但不能保证。在这种情况下,我是否过于偏执?
- 在握手中生成新的 ACK 通信端口,并在附加步骤中通过控制端口 (69) 将其发送给客户端
更新:
我设法解决了我的问题。我的问题是我没有尝试重用我的套接字。例如,我从端口 X 上的套接字发送了一些东西,但随后尝试在该端口上分配一个新套接字来监听 ACK,而不是仅仅重用旧套接字。