ICMP Port Unreachable是什么错误

fxbird 2006-04-28 03:58:25
我现在正在学习<<java网络编程》,书上有个例子,是做2个线程,一个发送udp包,另一个接收udp包,收发均使用同一个socket,但我一运行就提示:java.net.PortUnreachableException: ICMP Port Unreachable
发送线程类:
package test;

import java.net.*;
import java.io.*;

public class SenderThread extends Thread{
private InetAddress server;
private DatagramSocket socket;
private boolean stopped=false;
private int port;

public SenderThread(InetAddress server, int port) throws SocketException{
this.server = server;
this.port = port;
this.socket=new DatagramSocket();
this.socket.connect(server,port);
}

public void halt(){
this.stopped=true;
}

public DatagramSocket getSocket(){
return this.socket;
}

public void run() {

BufferedReader userInput=new BufferedReader(
new InputStreamReader(System.in)
);

try {
while(true){
if (stopped){
return;
}
String theLine=userInput.readLine();
if (theLine.equals(".")){
break;
}
byte[] data=theLine.getBytes();
DatagramPacket output=new DatagramPacket(data,data.length,server,port);
socket.send(output);
Thread.yield();
}
} catch (Exception e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
}

接收线程类:
package test;

import java.net.*;
import java.io.*;

public class ReceiverThread extends Thread{
DatagramSocket socket;
private boolean stopped=false;

public ReceiverThread(DatagramSocket socket) {
this.socket = socket;
}

public void halt(){
this.stopped=true;
}

public void run() {
byte[] buffer=new byte[3000];
while (true){
if (stopped){
return;
}
DatagramPacket dp=new DatagramPacket(buffer,buffer.length);
try {
socket.receive(dp);//异常出现在这行。!!!!!!!!!!!!!!!!
String s=new String(dp.getData(),0,dp.getLength());
System.out.println(s);
Thread.yield();
} catch (Exception e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
}
}

调用者:
package test;

import java.net.*;
import java.io.*;

public class UDPEchoClient {
public final static int DEFAULT_PORT=7;

public static void main(String[] args) {
try {
String hostname="localhost";
int port;

try {
port=Integer.parseInt(args[1]);
} catch (Exception e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
port=DEFAULT_PORT;
}


if (args.length>0){
hostname=args[0];
}

InetAddress ia=InetAddress.getByName(hostname);
SenderThread sender=new SenderThread(ia,port);
sender.start();

Thread receiver=new ReceiverThread(sender.getSocket());
receiver.start();
} catch (UnknownHostException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (Exception e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
}

...全文
4716 17 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
fxbird 2006-05-03
  • 打赏
  • 举报
回复
冷血动物的第二张专辑比第一张要好得多,很经典。第一张我买的是录音带,听起来效果也不太好。也许是同一个socket只能用于一种用途吧
hemiao_1993 2006-05-03
  • 打赏
  • 举报
回复
嘿嘿, 不知道还配叫冷血动物吗? 哈哈, 但是最喜欢的是<永远是个秘密>.
在CSDN上还能见到摇友, 不容易啊. 缘份啊.

不能用一个Socket是我猜的, 具体原因我也不清楚了, 反正既然用两个可以以后记着就用两个就成了.
fxbird 2006-05-02
  • 打赏
  • 举报
回复
嘿嘿,你知不知道,《昨天晚上我可能死了》就是冷血动物乐队唱的
fxbird 2006-05-02
  • 打赏
  • 举报
回复
为什么不可以呢?书上的例子就是用同一个的。难道它错了,作者可是这方面的专家啊。我用是的jdk1.5,难道是jdk的版本问题吗。以前可以,现在不可以了?
hemiao_1993 2006-05-01
  • 打赏
  • 举报
回复
收发不要用同一个Socket.
hemiao_1993 2006-04-30
  • 打赏
  • 举报
回复
ICMP不可达, 可能是你的网络把ICMP屏蔽了, 你可以试一下你的网络是否可以运行ICMP协议.
还有可能是PORT被屏蔽了.
做鸡真好吃 2006-04-30
  • 打赏
  • 举报
回复
最最后一次了~
fxbird 2006-04-30
  • 打赏
  • 举报
回复
我的代码和书上一样,你用的还是一样的啊
hemiao_1993 2006-04-30
  • 打赏
  • 举报
回复
哪个代码和书上一样? 你的还是我的. 原因就是这个啊, 我不是说了吗, 不能用一样的.
fxbird 2006-04-30
  • 打赏
  • 举报
回复
不对呀,楼上,你的收发socket不都是用的444吗,和我唯一的区别就是创建接收socket的时候没用传过来的发的socket,而是同样用444端口重新创建了一遍,代码和书上一样,书上就这么写的。
hemiao_1993 2006-04-30
  • 打赏
  • 举报
回复
原因已经找到, 是因为收发你共用了同一个Socket, 这是不行的. 当发送线程起来之后, 就把端口占用了, 接收的时候由于用的是同一个Socket, 结果发现端口已经被占用了, 引起了端口不可达的异常, 改动如下后就正常了(为了方便调试我去掉了一些无关的代码):
import java.net.*;
import java.io.*;

public class SenderThread extends Thread {
private InetAddress server;

private DatagramSocket socket;

// private boolean stopped = false;

private int port;

public SenderThread(InetAddress server, int port) {
this.server = server;
this.port = port;
try {
this.socket = new DatagramSocket();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// this.socket.connect(server, port);
}

/* public void halt() {
this.stopped = true;
}

public DatagramSocket getSocket() {
return this.socket;
}*/

public void run() {

BufferedReader userInput = new BufferedReader(new InputStreamReader(
System.in));

try {
while (true) {
/* if (stopped) {
return;
}*/
String theLine = userInput.readLine();
if (theLine.equals(".")) {
break;
}
byte[] data = theLine.getBytes();
DatagramPacket output = new DatagramPacket(data, data.length,
server, port);
socket.send(output);
Thread.yield();
}
} catch (Exception e) {
e.printStackTrace(); // To change body of catch statement use
// File | Settings | File Templates.
}
}
}

import java.net.*;
import java.io.*;

public class ReceiverThread extends Thread {
DatagramSocket socket;

private boolean stopped = false;

public ReceiverThread() {
try {
socket = new DatagramSocket(444);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public void halt() {
this.stopped = true;
}

public void run() {
byte[] buffer = new byte[3000];
while (true) {
if (stopped) {
return;
}
DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
try {
socket.receive(dp);// 异常出现在这行。!!!!!!!!!!!!!!!!
String s = new String(dp.getData(), 0, dp.getLength());
System.out.println(s);
Thread.yield();
} catch (Exception e) {
e.printStackTrace(); // To change body of catch statement use
// File | Settings | File Templates.
}
}
}
}

import java.net.*;
import java.io.*;

public class UDPEchoClient {
public final static int DEFAULT_PORT = 444;

public static void main(String[] args) {
try {
String hostname = "localhost";
int port = DEFAULT_PORT;

/*
* try { port=Integer.parseInt(args[1]); } catch (Exception e) {
* e.printStackTrace(); //To change body of catch statement use File |
* Settings | File Templates. port=DEFAULT_PORT; }
*
*
* if (args.length>0){ hostname=args[0]; }
*/

InetAddress ia = InetAddress.getByName(hostname);
SenderThread sender = new SenderThread(ia, port);
sender.start();

Thread receiver = new ReceiverThread();
receiver.start();
} catch (UnknownHostException e) {
e.printStackTrace(); // To change body of catch statement use
// File | Settings | File Templates.
} catch (Exception e) {
e.printStackTrace(); // To change body of catch statement use
// File | Settings | File Templates.
}
}
}
hemiao_1993 2006-04-30
  • 打赏
  • 举报
回复
我调试了一下你的程序, 确实有这个错误, 不知道是什么原因. 我另外写了一个两个进程的UDP通信, 是可以实现的. 不知道为什么你那个就会报错.
你完全是按照书上写的吗? 没有任何改动?
发送程序:UdpSend.java
import java.net.*;
public class UdpSend
{
public static void main(String [] args) throws Exception
{
DatagramSocket ds=new DatagramSocket();
String str="hello world";
DatagramPacket dp=new DatagramPacket(str.getBytes(),str.length(),
InetAddress.getByName("127.0.0.1"),3000);
ds.send(dp);
ds.close();
}
}

接收程序:UdpRecv.java
import java.net.*;
public class UdpRecv
{
public static void main(String [] args) throws Exception
{
DatagramSocket ds=new DatagramSocket(3000);
byte [] buf=new byte[1024];
DatagramPacket dp=new DatagramPacket(buf,1024);
ds.receive(dp);
String strRecv=new String(dp.getData(),0,dp.getLength()) +
" from " + dp.getAddress().getHostAddress()+":"+dp.getPort();
System.out.println(strRecv);
ds.close();
}
}
fxbird 2006-04-30
  • 打赏
  • 举报
回复
to hemiao_1993:
怎么知道是否可以运行icmp协议,再说我是发给自己,也没有发给别的机器啊。
ty263 2006-04-30
  • 打赏
  • 举报
回复
当我们给一个主机发送icmp包时,如果对方的主机不可达,就会返回ICMP Port Unreachable,有两种原因:
1。你的地址写的不对;
2。防火墙过滤了某些规则的包;

给分
fxbird 2006-04-29
  • 打赏
  • 举报
回复
这个问题很简单的,虽然代码挺长却极简单,高手在哪里
fxbird 2006-04-29
  • 打赏
  • 举报
回复
最后一次顶了。
fxbird 2006-04-28
  • 打赏
  • 举报
回复
我运行UDPEchoClient的参数是:localhost 3456

62,635

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧