背景:
- 我司通过kafka给第三方推送数据,web应用,使用kafka提供的jar包
- 第三方对我司暴露的服务器ip为AAA.AAA.AAA.AAA ,目的端口号为7036
- 限制我方只有ip为XXX.XXX.XXX.XXX的服务器可以访问第三方服务器,同时限制我司只有源端口号为固定的几个端口或某一范围可以访问第三方,例如3400~3500
知识点
一:
socket中对于本地端口的关闭和连接是有注释的(如下),大概意思就是当套接字被关闭,它不能立即用于网络使用,需创建一个新的套接字,立即使用会报错。
难道端口只能用一次吗?并不是,需要等系统自动释放,这个端口释放时间由系统层面决定。
/**
* Closes this socket.
* <p>
* Any thread currently blocked in an I/O operation upon this socket
* will throw a {@link SocketException}.
* <p>
* Once a socket has been closed, it is not available for further networking
* use (i.e. can't be reconnected or rebound). A new socket needs to be
* created.
*
* <p> Closing this socket will also close the socket's
* {@link java.io.InputStream InputStream} and
* {@link java.io.OutputStream OutputStream}.
*
* <p> If this socket has an associated channel then the channel is closed
* as well.
*
*/
public synchronized void close() throws IOException {
synchronized(closeLock) {
if (isClosed())
return;
if (created)
impl.close();
closed = true;
}
}
/**
* Returns the connection state of the socket.
* <p>
* Note: Closing a socket doesn't clear its connection state, which means
* this method will return {@code true} for a closed socket
* (see {@link #isClosed()}) if it was successfuly connected prior
* to being closed.
*
*注意:关闭套接字并不会清除它的连接状态,这意味着该方法将为关闭的套接字返回{@code true}(参见
*{@link #isClosed()}),如果它在关闭之前已经成功连接。
*
*/
public boolean isConnected() {
// Before 1.3 Sockets were always connected during creation
return connected || oldImpl;
}
/**
* Returns the binding state of the socket.
* <p>
* Note: Closing a socket doesn't clear its binding state, which means
* this method will return {@code true} for a closed socket
* (see {@link #isClosed()}) if it was successfuly bound prior
* to being closed.
*
* 注意:关闭套接字不清除其绑定状态,这意味着该方法将为关闭的套接字返回{@code true}(请参阅
* {@link #isClosed()}),如果它在关闭之前绑定成功的话。
*
*/
public boolean isBound() {
// Before 1.3 Sockets were always bound during creation
return bound || oldImpl;
}
二:
kafka的通信是基于tcp协议的,tcp的三次握手,每次的源端口号就是不同。
说辞:
一般来说,kafka服务端的端口,防火墙是要限制的,但是客户端的源端口,99%的场景都不会限制它。
我们基于kafka的客户端jar包开发,它是无法指定客户端的源端口,而理论上讲,socket可以指定客户端的源端口,但是涉及端口及时释放,基于socket实现kafka客户端协议,难度和工作量都会很大,如果贵方坚持限制源端口,我司可能要从商务层面商量下这个问题。