主机不可达和端口不可达

      主机不可达和端口不可达不都是连接不上嘛,会有什么区别呢?果真如此吗,我们来写个小程序来试试,在地址的位置上,我们第一次使用一个不存在的主机IP,第二次使用一个存在的主机IP,但端口不存在。

public static void main(String[] args) throws Exception
{
    Socket socket = new Socket();
    InetSocketAddress addr = new InetSocketAddress("121.14.0.29", 12345);
    socket.connect(addr);
}

     在Linux环境下,对于不存在的端口(主机是linux),程序马上就报连接错误,而对于主机不存在,非常地糟糕,运行了很就一直没有返回,为什么会有这种区别呢(windows的测试结果会不太一样,后面会有说明)?我们使用Ethereal抓包来看一下有什么区别:
     1.端口不存在
 
      很幸运,对于端口不存在,对方(linux)在IP层会直接发一个RST(Reset)响应直接终止掉连接,客户端直接把连接终止。在Windows环境下不太一样, 如果对方为Windows服务器,则不会回RST响应,这种情况下与主机不存在一致。
     2.主机不存在

    很不幸,在TPC/IP的Linux环境的实现中,客户端在连接请求包没有得到响应的时候,会不断进行重试(实现认为可能是丢包),时间间隔分别是2秒/6秒/12秒/25秒/50秒(指数级增长,到达50秒后会以这个频度重试,在本机测试的时候(Rethat Linux Enterprise V4)一直持续了3分9秒。这样当然非常地糟糕,所以在连接的时候设置一下超时时间是非常地重要滴(见下面)。在Windows环境下结果不太一样,Windows的TCP/IP实现上,客户端只会重试一次,间隔是10秒钟。

socket.connect(addr, 300); //设置超时时间为300豪秒

    另外有一件非常奇怪的事情,就是不管是主机不存在还是端口不存在,网关和主机并不会返回主机不存在或端口不存在的ICMP消息

### 使用Packet Tracer模拟分析ICMP主机不可达与网络不可达差错 #### ICMP主机不可达与网络不可达的概念 在网络通信中,当源主机尝试访问目标主机时,如果中间路由器无法找到通往目标网络的路径,则会返回“网络不可达”的错误消息;而如果路由器能够到达目标网络,但找不到具体的目标主机,则会返回“主机不可达”的错误消息。这些错误通常通过ICMP协议中的差错报文传递给源主机[^1]。 #### 在Packet Tracer中设置环境 为了模拟ICMP主机不可达与网络不可达的情况,可以在Packet Tracer中构建如下拓扑结构: - 创建两个子网(Network A Network B),分别连接不同的路由器。 - 配置PC设备作为源主机目标主机。 - 设置静态路由或默认路由以控制数据包转发行为。 #### 模拟ICMP网络不可达差错 要观察ICMP网络不可达的行为,可以采取以下措施之一: - **移除路由条目**:删除RouterA上的指向NetworkB的相关路由条目,使得它不知道如何抵达该目的地。 - **断开物理链路**:手动关闭连接至NetworkB的接口或者拔掉相应的电缆。 执行`ping`操作后,由于RouterA未能发现前往NetworkB的有效途径,因此向Source PC反馈一条Type=3 Code=0 (Destination Unreachable - Net unreachable)的消息[^2]。 #### 实现ICMP主机不可达测试 对于主机不可达场景,需满足的前提条件是存在可达性的网络层连通性,即至少有一台路由器知道怎样接近目的网络。然而,在那个特定的目的网上却不存在所指定的那个终端节点。可以通过下面的方法达成此效果: - 将Target Host从其所属交换机上解除关联; - 或者简单地禁用那部机器的操作系统下的主要服务端口监听器——比如停止Windows防火墙之外的一切对外提供服务的应用进程。 此时再次发起同样的探测请求动作的话,沿途经过的第一跳网关就会察觉到最终诉求对象已经消失不见,并依照规定构造出相应类型的回应帧回送给最初发出呼叫的那一方去告知这一事实状况了。这种情况下产生的应答类型同样是属于第三类别的范畴之内不过编码部分则改成了编号为一的形式表示Host Unreachable而已[^3]。 ```python import os def ping_test(ip_address): response = os.system(f"ping {ip_address}") if response == 0: print(f"{ip_address} is reachable.") else: print(f"{ip_address} is NOT reachable.") # Example usage of the function with an IP address that might be unreachable. ping_test("192.168.3.76") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值