当前位置: 首页 > 知识库问答 >
问题:

Java DatagramSocket receive()调用未阻塞/未引发SocketTimeoutException

别旻
2023-03-14

我很难理解为什么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块并导致屏幕上出现错误消息。

不幸的是,我什么也没得到 - 在连接之后放置一个打印语句.receive()调用显示一个无限循环。无限循环是可以预料到的,但是为什么我没有得到一个抛出的套接字超时异常?

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

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

共有1个答案

孔征
2023-03-14

我已解决了该问题。以前,数据语法插座具有 Inet索克特地址。现在,我没有将 InetSocket 地址传递给数据语法外壳构造函数,而是不传入任何内容:

connection = new DatagramSocket();

通过DatagramSocket发送的DatagramPackets将是具有InetSocketAddress的数据包。

 类似资料:
  • 我完全混淆了,,。 哪个是阻塞,哪个不是? 我的意思是如果我使用父进程是否等待子进程返回/才继续执行。 如何影响这些调用?

  • 本文向大家介绍node.js回调函数之阻塞调用与非阻塞调用,包括了node.js回调函数之阻塞调用与非阻塞调用的使用技巧和注意事项,需要的朋友参考一下 首先,node.js作为javascript运行平台,它采用了事件驱动和异步编程的方式,通过事件注册和异步函数,开发人员可以提高资源利用率,服务器的性能也能得到改善。其次,对于前端人来说,node.js作为js的运行平台,我们可以通过编写系统级或者

  • 在上一节中,我们看到了 take Effect 让我们可以在一个集中的地方更好地去描述一个非常规的流程。 重温一下登录流程示例: function* loginFlow() { while(true) { yield take('LOGIN') // ... perform the login logic yield take('LOGOUT') // ...

  • 问题内容: 我正在使用RXTX从串行端口读取数据。读取是在以下列方式产生的线程中完成的: SerialReader类实现Runnable并无限期地循环,从端口读取并将数据构造为有用的程序包,然后再将其发送给其他应用程序。但是,我将其简化为以下简单性: 当用户单击停止按钮时,将触发以下功能,从理论上讲,应关闭输入流并突破阻塞的byteChan.read(buffer)调用。代码如下: 但是,当我运行

  • 当我使用ExecutorService进行异步调用时,它会返回Future对象。根据它返回的布尔值,我必须记录异步调用的状态。 但当我试图从future对象调用get方法时,它会阻止主线程的执行。 是否可以解除屏蔽主线程执行?

  • 我有一个应用程序,通过点击按钮(该数字被定义)用户创建任务(可调用)做一些计算。我希望任务完成时能够做出反应。使用Future.get()阻止应用程序。有什么方法可以在Callable返回结果时做出反应吗?