Datagramsocket Receive Method Blocks Forever or Fails with RECVFROM() Timed Out (Doc ID 760945.1)

Last updated on JULY 05, 2017

Applies to:

Oracle Server - Enterprise Edition - Version: 10.2.0.1 to 11.1.0.7 - Release: to 11.1

Symptoms

Receiving datagrams via java.net.DatagramSocket receive() method inside the Oracle JVM fails with
error but sending datagrams works fine. Also the same code works fine outside the database

java.io.InterruptedIOException: recvfrom() timed out
Resource temporarily unavailable
at java.net.PlainDatagramSocketImpl.peekData(Native Method)
at java.net.DatagramSocket.receive(DatagramSocket.java:662)
at tester2.echoClient(tester2:33)

Changes

Steps to reproduce the error
------------------------
1) Create user and grant privileges 
 SQL> create user kiran identified by kiran
     default tablespace users
    temporary tablespace temp;
    
SQL> grant dba to kiran;
SQL> call dbms_java.grant_permission( 'KIRAN','SYS:java.net.SocketPermission','localhost:1024-', 'listen,resolve' );
SQL> call dbms_java.grant_permission( 'KIRAN','SYS:java.net.SocketPermission', '127.0.0.1:6636', 'accept,listen,connect,resolve' );

2) Java Code

EchoServer.java
-------------

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Date;

public class EchoServer extends Thread {
    protected Class c = null;
    protected DatagramSocket socket = null;
    protected boolean runFlag = true;
    
    public EchoServer(String name) {
        super(name);
        c = this.getClass();

        try { 
  socket = new DatagramSocket(6636); //specifying a port makes us a server
        } catch (Exception ex) {
                ex.printStackTrace(System.err);
        }
    }

    @Override
    public void run() {
        while (runFlag) {
            try {
                byte[] buf = new byte[1024];
                DatagramPacket packet = new DatagramPacket(buf, buf.length);
                socket.receive(packet);
                System.out.println(c.getName()+" recd: "+new String(buf).trim()+
" from "+packet.getAddress()+':'+packet.getPort());
                String dateString = new Date().toString();
                buf = dateString.getBytes();
                InetAddress address = packet.getAddress();
                int port = packet.getPort();
                packet = new DatagramPacket(buf, buf.length, address, port);
                socket.send(packet);
            } catch (IOException e) {
                e.printStackTrace();
                runFlag = false;
            }
        }
        socket.close();
    }

        public static void main(String[] args) {
          System.out.println(" In EchoServer ");
                EchoServer e = new EchoServer("foo");
                e.start();
        }
}

tester2.java
-------------

import java.math.BigDecimal;
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetSocketAddress;

public class tester2 {
  static InetSocketAddress foreignAddress = new InetSocketAddress("127.0.0.1",66
36);
  static DatagramSocket udpSocket = null;

  static final tester2 t = new tester2();

  public tester2() {
    try {
       System.out.println("In default constructor");
        udpSocket = new DatagramSocket();
        udpSocket.setSoTimeout(15000);
    } catch (Exception ex) {
        ex.printStackTrace(System.err);
    }
  }

  public static void echoClient(String msg) {
    byte[] buffer = new byte[65507];
    DatagramPacket dp = null;

    try {
     System.out.println("In echoclient"); 
     dp = new DatagramPacket(msg.getBytes(),msg.getBytes().length,foreignAddr
ess.getAddress(),foreignAddress.getPort());
        udpSocket.send(dp);
        buffer = new byte[65507]; 
   dp = new DatagramPacket(buffer,buffer.length,foreignAddress.getAddress()
,foreignAddress.getPort());
               System.out.println("Receive data");
        udpSocket.receive(dp);
 System.out.println("Sent: "+msg+" recvd: "+new String(dp.getData()).trim());
    } catch (Exception ex) {
        ex.printStackTrace(System.err);
    }
  }

    public static void main(String[] args) {
        echoClient("Hello there sonny boy from main...");
  }
}

3) Compile EchoServer.java and load tester2.java into KIRAN schema

> javac EchoServer.java
> loadjava -user kiran/kiran -resolve -v tester2.java

4) Start EchoServer

> java EchoServer
In EchoServer

5) Log in as Kiran , create pl/sql wrapper

create or replace package tester2 is
        procedure echo_client(msg varchar2)
        as language java
        name 'tester2.echoClient(java.lang.String)';
end tester2;
/
show errors

6) Execute the pl/sql wrapper code

SQL> set serveroutput on size 90000
SQL> call dbms_java.set_output(90000);

Call completed.

SQL> call tester2.echo_client('This is a test message');
In default constructor
In echoclient
Receive data
java.io.InterruptedIOException: recvfrom() timed out
Resource temporarily unavailable
at java.net.PlainDatagramSocketImpl.peekData(Native Method)
at java.net.DatagramSocket.receive(DatagramSocket.java:662)
at tester2.echoClient(tester2:33)

Call completed.

7) Executing tester2.java outside the database works fine

> java tester2
In default constructor
In echoclient
Receive data
Sent: Hello there sonny boy from main... recvd: Tue Jan 13 22:02:38 GMT 2009

Cause

Sign In with your My Oracle Support account

Don't have a My Oracle Support account? Click to get started

My Oracle Support provides customers with access to over a
Million Knowledge Articles and hundreds of Community platforms