连接到服务器的Java套接字块

Dur*_*rin 6 java sockets port blocking

我正在尝试使用Java套接字连接到服务器.我正在尝试从端口80连接到90

int port;
Socket clientsocket;
String hostname = "www.google.com";

for(port = 80;port<=90; port++){
  try{
    clientsocket = new Socket(hostname,port);
    System.out.println("Connection at port " + port + "\t" + clientsocket.isConnected());
    clientsocket.close();
  }
  catch(Exception e){
    System.out.println(e.getMessage());
  }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试连接到任何网站,如google.com或w3schools.com时,我的程序挂起了socket()除80之外的端口号码的呼叫.由于这些网站不在端口81-90上提供,它应该引发异常,但它被阻止.对于80端口,它工作正常.当我尝试连接到我的机器上安装的apache服务器时,它不会阻止任何端口号并给我连接拒绝错误,这是明显的行为.那么为什么会这样呢?提前致谢.

Ste*_*n C 16

当我尝试连接到任何网站,如google.com或w3schools.com时,我的程序挂起socket()调用端口号,除了80.由于这些网站没有在端口81-90上服务,它应该引发异常,但它得到了受阻.

这几乎肯定不是Java的做法.

当您调用Socket(String, int)构造函数时,JVM会要求操作系统尝试使用提供的端口号建立与提供的名称对应的IP地址的连接.假设我们正在讨论TCP/IP,操作系统会发送TCP"SYN"消息,并等待响应:

  • 如果响应是'SYN-ACK',则继续按照协议建立连接; 请参阅http://en.wikipedia.org/wiki/Transmission_Control_Protocol#Connection_establishment.

  • 如果响应是'RST'(重置),则连接失败,这会导致Java"连接被拒绝"异常.(这通常是'SYN'进入远程服务器时发生的情况,只是发现在您尝试连接的端口上没有"侦听"应用程序.)

  • 如果响应是某种ICMP消息(例如,ICMP目标不可达),则通常会导致连接请求立即失败,并导致Java异常.

  • 如果没有响应,操作系统将再次尝试,并再次尝试.根据Java默认连接超时(或显式超时),此过程可能会持续很长时间.

所以最有可能发生的事情就是在某个时髦的端口上过滤掉"SYN"消息,并简单地将它们丢弃.它可能是PC上的本地防火墙软件,网关中的防火墙软件,或ISP的网络,或者您尝试与之通信的远程系统中的软件.或者这可能发生在回来的'SYN-ACK'消息中.

无论哪种方式,阻塞/超时行为都是TCP/IP网络所固有的,并且无法在OS或Java级别进行准确诊断.你只需要调整你的期望.(或设置较短的连接超时...)

  • 这是如此精美的写作和启发.谢谢你的吨. (3认同)