繁体   English   中英

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

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

我无法理解为什么 UDP 连接的接收调用似乎没有阻塞。 任何帮助,将不胜感激。

基本上,完整的代码应该通过 UDP 读取文件的字节段并将其发送到另一个正在侦听特定端口的正在运行的进程,以便进程可以重建(副本)文件。 然而,在这种情况下,目前还没有这样的侦听器。 下面的代码只包含我认为有问题的部分。

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;
    }
}

从我认为应该发生的情况来看,考虑到指定端口没有侦听器的情况,接收调用应该阻塞,等待永远不会到来的确认,直到超时值到期,在这种情况下,应该是 SocketTimeoutException抛出,激活适当的 catch 块并导致错误消息出现在屏幕上。

不幸的是我什么也没得到 - 在 connection.receive() 调用之后放置一个打印语句显示一个无限循环。 无限循环是意料之中的,但为什么我没有收到抛出的 SocketTimeoutException?

到目前为止我遇到的其他问题:

  1. 数据报套接字上的 setSotimeout
  2. DatagramSocket 不抛出 SocketTimeout - Java
  3. 向 DatagramSocket 添加超时 - receive()

我已经解决了这个问题。 以前 DatagramSocket 有 InetSocketAddress。 现在,我没有将 InetSocketAddress 传递给 DatagramSocket 构造函数,而是不传递任何内容:

connection = new DatagramSocket();

通过 DatagramSocket 发送的 DatagramPackets 将是具有 InetSocketAddress 的那个。

暂无
暂无

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

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