【问题标题】:How to set a timeout in a UDP client for when a packet is not sent from server?当没有从服务器发送数据包时,如何在 UDP 客户端中设置超时?
【发布时间】:2016-03-24 20:58:41
【问题描述】:

我正在编写一个关于 UDP 套接字编程的简单程序。我正在使用数据报套接字。我必须将数据包从客户端发送到服务器。然后服务器随机决定是否发回一个数据包。如果已发送,客户端必须接受数据包或等待 2 秒并假设数据包丢失。我无法处理丢包的情况。

    System.out.println("Receiving message...");
    dsock.receive(dpack); // receive the packet
    System.out.println("Message received");

如果发送了数据包,一切正常,但是如果没有发送数据包并且我仍然存在这行代码,我该如何处理?

【问题讨论】:

    标签: java sockets networking udp timeout


    【解决方案1】:

    您可以更改套接字的超时并接收消息,直到达到超时,如下所示:

    try {
        dsock = new DatagramSocket();
        byte[] buf = new byte[1000];
        DatagramPacket dpack = new DatagramPacket(buf, buf.length);
    
        //...
    
        dsock.setSoTimeout(1000);   // set the timeout in millisecounds.
    
        while(true) {        // recieve data until timeout
            try {
                 System.out.println("Receiving message...");
                 dsock.receive(dpack); // receive the packet
                 System.out.println("Message received");
            }
            catch (SocketTimeoutException e) {
                // timeout exception.
                System.out.println("Timeout reached!!! " + e);
                dsock.close();
            }
        }
    catch (SocketException e) {
        System.out.println("Socket closed " + e);
    
    }
    

    【讨论】:

    • 好的,它就是这样工作的,但是它会抛出一个套接字关闭异常。知道如何抓住它吗?
    【解决方案2】:

    您正在搜索dsock.setSoTimeout(2 * 1000) (2*1000 = 2000 ms = 2s)。这是doc

    使用指定的超时启用/禁用 SO_TIMEOUT,以毫秒为单位。将此选项设置为非零超时后,对此 DatagramSocket 的 receive() 调用将仅阻塞此时间量。如果超时到期,则会引发 java.net.SocketTimeoutException,尽管 DatagramSocket 仍然有效。必须在进入阻塞操作之前启用该选项才能生效。超时必须 > 0。超时为零被解释为无限超时。

    这会在两秒后引发 SocketTimeoutException,所以你必须抓住它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-07
      • 2017-07-30
      • 2012-11-28
      相关资源
      最近更新 更多