繁体   English   中英

如何在Java中设置客户端端口号?

[英]How to set client port number in java?

服务器决定接收客户端连接后,谁能告诉我如何设置客户端端口号。 我希望客户端的端口号应在50000到60000之间。

如果您询问如何对服务器进行编码以设置客户端的端口,那么答案是您不能。 客户端选择自己的端口,并且在涉及服务器时该端口已经在使用中。


如果您询问如何对客户端进行编码,以选择与服务器连接的本地端口,则可以查看Socket文档。

如果您未指定端口,则操作系统会根据其临时端口范围提供任意端口号。

如果您确实指定了本地端口,例如使用构造函数public Socket(InetAddress address, int port, InetAddress localAddr, int localPort)则客户端将尝试绑定到该本地端口。

但是,如果端口不可用,这将失败。 我们通常要求操作系统提供临时端口的原因是为了避免当同一客户端的两个实例或套接字保持TIME_WAIT状态时出现“使用中的地址”失败。

没有任何API可以让您向OS请求给定范围内的临时端口。

最好的办法是请求一个任意端口,然后循环尝试,直到获得所需范围内的端口:

 Socket socket;
 do {
    socket = new Socket();
    socket.bind(null); // null means any local address, ephemeral port
 } while (! isInRange(socket.getLocalPort());
 socket.connect(...);

这种做法的效率很低; 您可以创建和丢弃任意数量的套接字,然后再踩在可接受的套接字上。 如果您希望的范围是操作系统临时范围的一个适当大小的部分,那么这是一种合理的方法。

或者,您可以遍历可接受的范围,捕获绑定错误并重试:

    Socket socket = new Socket();
    for ( int port = MIN_PORT ; port <= MAX_PORT; port++ )
    {
        try {
            s.bind(new InetSocketAddress(port));
            break;
        } catch (IllegalArgumentException | IOException e) {
            // try the next port
        }
        // deal with not having found a suitable port
    }
    socket.connect(...);

这有不同的效率低下,如果客户端频繁并发运行,这将变得尤为重要。 您将不断地在范围较低端的端口上进行“战斗”。 如果必须使用此方法,则值得对其进行修改,以至少开始查看范围内的随机位置。


如果您这样做的动机是绕过防火墙规则,请尝试解决(愚蠢,毫无意义的)防火墙规则。 但是,有些客户端确实使用了我描述的方法,因为有时防火墙管理员不会放弃。

您需要的构造函数是

public Socket(InetAddress address,
              int port,
              InetAddress localAddr,
              int localPort)

https://docs.oracle.com/javase/8/docs/api/java/net/Socket.html#Socket-java.net.InetAddress-int-java.net.InetAddress-int-

此方法允许您提供特定的源端口。 您可以随机选择一个,然后重试(如果已使用)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM