用DatagramSocket通信的问题? DatagramPacket packet = new DatagramPacket(buf, buf.length, addr, port);这句中的addr,和port是指定open的地址,端口的!如果没有当然会出错! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 至于你send了但对方收不到,这才是说明了UDP得特征:就是不可靠性!(谁说过数据包时面相无联结的!?它只是为了效率降低了一点可靠性的SOCKET)给你一段话:<thinking java>TCP根据该协议的设计宗旨,它具有高度的可靠性,而且能保证数据顺利抵达目的地。换言之,它允许重传那些由于各种原因半路“走失”的数据。而且收到字节的顺序与它们发出来时是一样的。当然,这种控制与可靠性需要我们付出一些代价:TCP 具有非常高的开销。还有另一种协议,名为“用户数据报协议”(UDP),它并不刻意追求数据包会完全发送出去,也不能担保它们抵达的顺序与它们发出时一样。我们认为这是一种“不可靠协议”(TCP 当然是“可靠协议”)。听起来似乎很糟,但由于它的速度快得多,所以经常还是有用武之地的。对某些应用来说,比如声音信号的传输,如果少量数据包在半路上丢失了,那么用不着太在意,因为传输的速度显得更重要一些。 我这里省略了一下,addr,port是对方的IP和端口,只要对方程序在运行,这些代码都没有问题,但若对方不在运行,一但调用sock.send,在sock.receive就会抛出一个异常:java.net.SocketException: Connection reset by peer: Datagram peek failed但数据报不是面向无连接的吗,对方收不到应该不作任何处理才对呀,我的sock只绑定了本地接收端口,sock.receive应该可以接收任何地方发来的数据报,为什么会出现这个异常呢? UDP协议是面向无连接的,但是系统一般都提供connect方法,目的是绑定目标主机和端口。方法调用成功并不表示本机与目标机已经建立物理连接,而只是在本机操作系统中注册了一下。以后本UDP端口将不发送或接收除了已绑定了的目标主机端口的任何数据报。请参阅W.Richard Stevens《UNIX网络编程 第一卷》第8、25章。 如果receive收不到应该阻塞的,不应该出错。你的send和receive什么关系?为什么调send,receive也运行? 我试了一个上午,大概弄清楚什么回事了,我的send和receive是用同一个sock,其中receive是在一个线程的一个死循环内不停调用的,当没有数据时receive被阻塞,当我用send向一个不存在的对端发送时,可能由于IP协议会返回表示目的不可达的ICMP包,此时receive就抛出了Datagram peek failed的异常。我将send和receive分用两个DatagramSocket实现,就不会出现这个异常了。但是按UDP协议,当目的不可达时不应该作任何处理,我用C编的程序中就不会出现这种情况。本来我是想用一个socket就实现与所有客户端的通信,现在必须对每个客户端都创建一个socket才行了。不知那位高手有这方面的经验,这样解决最好? 我在1.4/1.3.1+Win2000下试验,用同一个socket没有这个错误,恐怕还有别的原因吧,你的版本是多少? 我是用jdk1.31+win2000,刚做了一个简单例子,帮助说明问题://UdpTest.javaimport java.net.*;import java.io.*;public class UdpTest { public static void main(String[] args) { DatagramSocket sock = null; byte[] buf1 = new byte[1000]; DatagramPacket packet1 = new DatagramPacket(buf1, buf1.length); byte[] buf2 = new byte[1000]; InetAddress addr = null; try { sock = new DatagramSocket(8888); System.out.println("start"); try { addr = InetAddress.getByName("localhost"); } catch (UnknownHostException e) { System.out.println(e); } DatagramPacket packet2 = new DatagramPacket(buf2, buf2.length, addr, 9999); sock.send(packet2); sock.receive(packet1); } catch (SocketException e) { System.out.println("sock error:"+e); e.printStackTrace(); } catch (IOException e) { System.out.println("io error:"+e); e.printStackTrace(); } finally { sock.close(); } }}运行后马上报告异常,若把sock.send(packet2)注释掉,则程序阻塞在sock.receive。若先在本机启动另一socket通信程序,侦听UDP端口9999,再运行本程序则一切正常。 我说的参考资料你有没有看?对方机器没有程序在端口上接收的话,对方机器会返回一个“目标不可到达”的ICMP包,本地主机接收到该包后一般会把它丢弃,只有两种情况例外,一:你的UDP SOCKET是已经“connect”到对方机器的端口上的;二:本地主机操作系统是win2000,它会把该ICMP包发送给应用程序,导致JAVA的receive方法抛出一个“socket已关闭”的例外;所以在win2000上肯定会存在你提到的问题,同样的程序在NT和UNIX上都正常。这是我在以前一个项目中测了好多台机器(包括3台win2000,3台NT,1台HP UNIX, 1台SOLARIS)得出的结论。 恩,hyhong_h(黄黄)说的第二个情况是原因所在,不过这个问题在1.4中已经得到了修正。另外在其他版本中如果你在receive出错后再receive一次也能继续。 如何用Java语言判段一个文件已经打开(如Excel)! File的listFiles一问 关于继承问题 什么错误 多事件处理怎么只有一个显示输入字符 如何把一张图片下载到本地? 最基本的问题,求教。 JBuild 6的IDE环境问题 请问用JBuilder5怎样打包? 小问题,不忙就看看 static在类定义中的作用 程序运行正常为什么无法显示结果???
给你一段话:<thinking java>
TCP根据该协议的
设计宗旨,它具有高度的可靠性,而且能保证数据顺利抵达目的地。换言之,它允许重传那些由于各种原因
半路“走失”的数据。而且收到字节的顺序与它们发出来时是一样的。当然,这种控制与可靠性需要我们付
出一些代价:TCP 具有非常高的开销。
还有另一种协议,名为“用户数据报协议”(UDP),它并不刻意追求数据包会完全发送出去,也不能担保它
们抵达的顺序与它们发出时一样。我们认为这是一种“不可靠协议”(TCP 当然是“可靠协议”)。听起来
似乎很糟,但由于它的速度快得多,所以经常还是有用武之地的。对某些应用来说,比如声音信号的传输,
如果少量数据包在半路上丢失了,那么用不着太在意,因为传输的速度显得更重要一些。
java.net.SocketException: Connection reset by peer: Datagram peek failed
但数据报不是面向无连接的吗,对方收不到应该不作任何处理才对呀,我的sock只绑定了本地接收端口,sock.receive应该可以接收任何地方发来的数据报,为什么会出现这个异常呢?
我将send和receive分用两个DatagramSocket实现,就不会出现这个异常了。
但是按UDP协议,当目的不可达时不应该作任何处理,我用C编的程序中就不会出现这种情况。本来我是想用一个socket就实现与所有客户端的通信,现在必须对每个客户端都创建一个socket才行了。
不知那位高手有这方面的经验,这样解决最好?
//UdpTest.java
import java.net.*;
import java.io.*;public class UdpTest {
public static void main(String[] args) {
DatagramSocket sock = null;
byte[] buf1 = new byte[1000];
DatagramPacket packet1 = new DatagramPacket(buf1, buf1.length);
byte[] buf2 = new byte[1000];
InetAddress addr = null;
try {
sock = new DatagramSocket(8888);
System.out.println("start");
try {
addr = InetAddress.getByName("localhost");
} catch (UnknownHostException e) {
System.out.println(e);
}
DatagramPacket packet2 = new DatagramPacket(buf2, buf2.length, addr, 9999);
sock.send(packet2);
sock.receive(packet1);
} catch (SocketException e) {
System.out.println("sock error:"+e);
e.printStackTrace();
} catch (IOException e) {
System.out.println("io error:"+e);
e.printStackTrace();
} finally {
sock.close();
}
}
}运行后马上报告异常,若把sock.send(packet2)注释掉,则程序阻塞在sock.receive。
若先在本机启动另一socket通信程序,侦听UDP端口9999,再运行本程序则一切正常。