Java DatagramSocket超时但实际上已收到

时间:2014-08-28 07:16:49

标签: java socketexception

我使用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();我转发了代码。

2 个答案:

答案 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();
    }

虽然您可能会注意到代码类似,但概念不同。

找到问题比找到解决问题的方法更好,我想!

如果我的意见不对,希望有人能纠正。