我使用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中测试),我认为fult不是服务器端的。但是什么可能导致超时?
为什么服务器会向我发送消息,但我无法在程序中收到消息?
我的Java版本是7,在我的计算机上禁用防火墙没有区别......
任何建议都将不胜感激!
编辑:虽然问题不在于socket.close();我转发了代码。
答案 0 :(得分:1)
您可以尝试一些事项。
首先,请先尝试调用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);
如果其他所有方法都失败了,请尝试{{1}},这将导致timeout to be set to infinite。但我有一种感觉,这只是掩盖真正问题的黑客。
答案 1 :(得分:0)
感谢大家的帮助! 我问我的同事,我应该采取另一种方式:打开我自己的服务器部分以接收返回的消息。
我从其他人那里听说过java可能没有得到适当的回复消息(也许这就是我总是超时的原因!),因为发送部分没问题,只需打开关于收听包的服务器部分,我就可以收到来自我想要的服务器的消息!
请注意,您应该使用目标服务器的相同端口,这样您也可以获得自己发送的包。只需过滤程序的发送地址即可。
服务器端和完整概念是这样的:
static DatagramSocket socket2;
public static void main(String[] args) {
// TODO Auto-generated method stub
// Open my own server part to listen messages from broadcast returned
listen();
// Sending UDP broadcast in this part as question implied
}
public static void listen() {
new Thread() {
public void run() {
try{
socket2 = new DatagramSocket(10000);
socket2.setBroadcast(true);
byte[] recvBuf = new byte[1024];
while (true) {
DatagramPacket packet2 = new DatagramPacket(recvBuf, recvBuf.length);
try{
socket2.receive(packet2);
System.out.println("Discovery packet received from: " + packet2.getAddress().getHostAddress());
System.out.println("Packet received; data: " + new String(packet2.getData()));
String message = new String(packet2.getData());
System.out.println("Received: "+message);
}catch(Exception ex){
System.out.println("Cannot receive package: " + ex.getMessage());
}
}
}catch(Exception ex){
socket2.close();
System.out.println("Server side problem occured: " + ex.getMessage());
}
}
}.start();
}
虽然您可能会注意到代码类似,但概念不同。
找到问题比找到解决问题的方法更好,我想!
如果我的意见不对,希望有人能纠正。