ServerSocket accept()方法

时间:2010-11-29 20:03:28

标签: java

当我使用ServerSocket类的accept方法时,谁知道如何选择端口?是否可以为方法可以选择的端口定义范围?我可以按顺序逐个接收端口吗?

ServerSocket sSocket = new ServerSocket(5050);
Socket socket = sSocket.accept();

From the book

5 个答案:

答案 0 :(得分:22)

图表不正确(并列在O'Reilly网站的unconfirmed errata上)。

客户端随机选择端口(您不需要在Java中执行任何特殊操作)并在您指定的任何端口上连接到服务器。使用netstat命令行工具,您可以看到 - 首先,只是没有客户端的侦听服务器套接字:

simon@lucifer:~$ netstat -n -a
Active Internet connections (including servers)
Proto Recv-Q Send-Q  Local Address          Foreign Address     (state)
...
tcp46      0      0  *.5050                 *.*                 LISTEN
...

(还有很多其他条目,我刚刚删除了不相关的条目)

现在有1个客户端从本地主机(127.0.0.1)连接:

simon@lucifer:~$ netstat -n -a
Active Internet connections (including servers)
Proto Recv-Q Send-Q  Local Address          Foreign Address     (state)
...
tcp4       0      0  127.0.0.1.64895        127.0.0.1.5050      ESTABLISHED <- 1
tcp4       0      0  127.0.0.1.5050         127.0.0.1.64895     ESTABLISHED <- 2
tcp46      0      0  *.5050                 *.*                 LISTEN      <- 3
...

由于客户端从同一台机器连接,我们看到两个已建立的连接 - 一个从客户端到服务器(1),另一个从服务器到客户端(2)。它们具有相反的本地和外部地址(因为它们彼此交谈)并且您可以看到服务器端仍在使用端口5050,而原始服务器套接字(3)继续在同一端口上侦听。

(这些来自Mac,但Windows / Linux也有netstat提供类似的输出)

答案 1 :(得分:5)

当您说新的ServerSocket(5050)时,

选择了该端口。关于为接受的套接字使用不同端口的所有内容都是100%BS。

答案 2 :(得分:3)

TCP连接由四部分组成:

  • 客户端IP
  • 客户端端口
  • 服务器IP
  • 服务器端口

例如,可以有多个客户端连接到同一个服务器端口 - 只要客户端没有相同的IP 相同的prt,就可以了。对于那部分,操作系统会照顾。

所以只听一个端口就可以了。

答案 3 :(得分:0)

ServerSocket将端口定义为构造函数的一部分。 如果未指定端口,则套接字不受约束(即无法访问)。

要获取连接Socket的端口,请使用getPort()而不是getLocalPort()。第二个将为您提供服务器上的端口。

答案 4 :(得分:0)

您可以将0作为端口号传递,以在任何空闲端口上创建服务器套接字,或者创建这样的方法为给定范围内的任何空闲端口创建服务器套接字:

public java.net.ServerSocket createServerSocket(int rangeStart, int rangeEnd)
                            throws java.io.IOException {
  for(int port=rangeStart; port<=randeEnd; port++) {  
    try {
      return new ServerSocket(port);
    } catch(java.net.BindException be) {
      // debug/warning here
      continue;
    }
  }
  throw new java.io.IOException("Failed to create a server socket, all ports between " +
                                rangeStart + " - " + rangeEnd + " are already in use.");
}

循环不会处理另一个异常(例如SecurityException),但您可以添加它。