我使用WireShark测试结果很奇怪,结果表明我的代码可以通过套接字成功发送消息。但是,即使我从服务器收到消息,我的程序也会抛出Timeout
异常。
我不知道为什么会有超时问题。
我的代码很简单:
static Timer timer = new Timer();
try {
DatagramSocket c = new DatagramSocket();
c.setBroadcast(true);
byte[] sendData = "messageToServer".getBytes();
try {
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getByName("255.255.255.255"), 10000);
c.connect(InetAddress.getByName("255.255.255.255"), 10000);
c.send(sendPacket);
} catch(Exception ex) {
System.out.println(ex.toString());
}
timer.schedule(new receiveTask(), 2000);
} catch(Exception ex) {
System.out.println(ex.toString());
}
我使用计时器来延迟从服务器接收消息。
receiveTask
类如下所示:public class receiveTask extends TimerTask {
@Override
public void run() {
// TODO Auto-generated method stub
try {
DatagramSocket c2 = new DatagramSocket();
c2.setSoTimeout(10000);
byte[] recvBuf = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(recvBuf, recvBuf.length);
String message = "";
while (true) {
c2.receive(receivePacket);
System.out.println("Receive packet from Server");
message=new String(receivePacket.getData()).trim();
System.out.println(message);
System.out.println("Close the connection of server socket");
}
} catch(Exception ex) {
System.out.println(ex.toString());
}
}
}
在
SocketTimeOut
类中引发receiveTask
异常。由于服务器可以向我发送消息(在WireShark中进行了测试),所以我认为该实现不是在服务器端。但是什么原因导致超时呢?
为什么服务器向我返回一条消息,但我的程序无法接收到该消息?
我的Java版本是7,在我的计算机上禁用防火墙没有区别。
任何建议将被认真考虑!
编辑:虽然问题不是关于socket.close();我删除了代码。
最佳答案
您可以尝试一些方法。
首先,尝试更早调用timer.schedule(new receiveTask(), 2000);
,以便您的receiveTask
准备好在发送任何消息之前接收消息。
其次,将您的c.close()
语句移到finally
子句,尤其是while
的receiveTask
循环内的那个子句,以确保套接字不会过早关闭。所以代码看起来像
DatagramSocket c2 = null;
try{
c2 = new DatagramSocket();
c2.setSoTimeout(10000);
byte[] recvBuf = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(recvBuf, recvBuf.length);
String message = "";
while(true){
c2.receive(receivePacket);
System.out.println("Receive packet from Server");
message=new String(receivePacket.getData()).trim();
System.out.println(message);
System.out.println("Close the connection of server socket");
}
}catch(Exception ex){
System.out.println(ex.toString());
} finally{
if(c2 != null)
c2.close();
}
如果所有其他方法均失败,请尝试
c2.setSoTimeout(0);
,这将导致timeout to be set to infinite。但是我感觉这只是掩盖真正问题的技巧。