简体   繁体   English

Java DatagramSocket receive() 调用不阻塞/不抛出 SocketTimeoutException

[英]Java DatagramSocket receive() call not blocking / not throwing SocketTimeoutException

I'm having trouble understanding why the receive call for a UDP connection does not seem to be blocking.我无法理解为什么 UDP 连接的接收调用似乎没有阻塞。 Any help would be appreciated.任何帮助,将不胜感激。

Basically, the full code is supposed to read and send byte segments of a file over via UDP to another running process listening at a specific port so that that process can then reconstruct (a copy) of the file.基本上,完整的代码应该通过 UDP 读取文件的字节段并将其发送到另一个正在侦听特定端口的正在运行的进程,以便进程可以重建(副本)文件。 In this case however there is no such listener as of yet.然而,在这种情况下,目前还没有这样的侦听器。 The code below only includes the sections which I think the trouble is in.下面的代码只包含我认为有问题的部分。

import java.util.*;
import java.io.*;
import java.nio.*;
import java.net.*;

//... setup code ...

Datagram connection = null;
try {
    address = new InetSocketAddress(hostName, portNum); //Assume the hostName and portNum are valid (i.e. localhost, port 8250)
    connection = new DatagramSocket(address);
    connection.setSoTimeout(100); //This doesn't seem to work, even if I set this to 1000000
} catch (IOException e) {
    //Quit
    System.out.println(ERROR_UNABLE_TO_CONNECT);
    return;
}

//... read contents from sourceFile and create a DatagramPacket for sending first few bytes ...

boolean received = false;
byte[] ackPacketBuffer = new byte[1000];
DatagramPacket ackPacket = new DatagramPacket(ackPacketBuffer, ackPacketBuffer.length);
while(!received) { 
    try {
        connection.send(fileNamePacket); //fileNamePacket can be treated as the packet to be sent
        connection.receive(ackPacket); //From my understanding, this should block at least for the set time, before throwing SocketTimeoutException

        //... do some checks on the ackPacket, set received flag to be true if successful so that loop is broken...

    } catch (SocketTimeoutException e) {
        //Packet potentially lost, resend
        System.out.println(ERROR_TIMEOUT);
        continue;
    } catch (IOException e) {
        System.out.println(ERROR_SOCKET_WRITE);
        continue;
    }
}

From what I think should happen, given the scenario for which there is no listener for the specified port , the receive call should block, waiting for an acknowledgement which should never come, until the timeout value has expired, in which case a SocketTimeoutException should be thrown, activating the appropriate catch block and causing an error message to appear on the screen.从我认为应该发生的情况来看,考虑到指定端口没有侦听器的情况,接收调用应该阻塞,等待永远不会到来的确认,直到超时值到期,在这种情况下,应该是 SocketTimeoutException抛出,激活适当的 catch 块并导致错误消息出现在屏幕上。

Unfortunately I get nothing - placing a print statement after the connection.receive() call shows an infinite loop.不幸的是我什么也没得到 - 在 connection.receive() 调用之后放置一个打印语句显示一个无限循环。 The infinite loop is to be expected, but why is it that I'm not getting a thrown SocketTimeoutException?无限循环是意料之中的,但为什么我没有收到抛出的 SocketTimeoutException?

Other questions which I have encountered so far:到目前为止我遇到的其他问题:

  1. setSotimeout on a datagram socket 数据报套接字上的 setSotimeout
  2. DatagramSocket not throwing SocketTimeout - Java DatagramSocket 不抛出 SocketTimeout - Java
  3. Adding timeout to DatagramSocket - receive() 向 DatagramSocket 添加超时 - receive()

I have resolved the issue.我已经解决了这个问题。 Previously the DatagramSocket had the InetSocketAddress.以前 DatagramSocket 有 InetSocketAddress。 Now, instead of passing in the InetSocketAddress to the DatagramSocket constructor, I do not pass in anything:现在,我没有将 InetSocketAddress 传递给 DatagramSocket 构造函数,而是不传递任何内容:

connection = new DatagramSocket();

The DatagramPackets sent through the DatagramSocket will be the one that has the InetSocketAddress instead.通过 DatagramSocket 发送的 DatagramPackets 将是具有 InetSocketAddress 的那个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM