How to Open TCP Connections with UTL_TCP

Connect to any host and port from PL/SQL, write and read text lines, and speak simple protocols such as HTTP by hand.

UTL_TCP is the lowest level of PL/SQL networking: it opens a plain TCP connection to a host and port and lets you write and read lines or bytes. UTL_HTTP and UTL_SMTP are built on it. Use it directly for simple text protocols that have no package of their own.

Code for This Guide

The main examples are in the examples/pkg-files-network folder of the Oracle Database 26ai code repository on GitHub, each with its output. They use NIMBUS, the sample schema of a fictional airline, which you can install with the scripts in the setup/nimbus folder.

They come from Oracle Database 26ai SQL and PL/SQL Book.

Syntax

c := utl_tcp.open_connection(remote_host, remote_port, charset => 'AL32UTF8',
                             tx_timeout => seconds);
n := utl_tcp.write_line(c, text);
utl_tcp.flush(c);
line := utl_tcp.get_line(c, remove_crlf => true);
utl_tcp.close_connection(c);

Reading after the server closes the connection raises UTL_TCP.END_OF_INPUT. The host and port need an access control entry with the connect privilege.

The examples talk to the local test server, setup/netlab/server.mjs in the repository.

Speak HTTP by Hand

Example:

declare
  c      utl_tcp.connection;
  v_n    pls_integer;
  v_line varchar2(1024);
begin
  c := utl_tcp.open_connection(remote_host => 'host.docker.internal', remote_port => 8099,
                               charset => 'AL32UTF8');
  v_n := utl_tcp.write_line(c, 'GET /notices HTTP/1.0');          -- HTTP, written by hand
  v_n := utl_tcp.write_line(c, 'Host: host.docker.internal');
  v_n := utl_tcp.write_line(c);
  utl_tcp.flush(c);
  begin
    loop
      v_line := utl_tcp.get_line(c, remove_crlf => true);
      if v_line is null or v_line not like 'Date:%' then    -- skip the changing date
        dbms_output.put_line(v_line);
      end if;
    end loop;
  exception
    when utl_tcp.end_of_input then                       -- the server closed the connection
      utl_tcp.close_connection(c);
  end;
end;
/

Output:

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Connection: close

Gate B12: boarding from 21:30
Lounge: open until 23:00
Wi-Fi: NimbusGuest

PL/SQL procedure successfully completed.

The block writes an HTTP request line, a Host header, and an empty line, then reads the raw response: status line, headers, an empty line, and the body. The Date header is skipped since it changes every run. END_OF_INPUT ends the loop when the server closes the connection.

Read a Server Greeting

Example:

declare
  c      utl_tcp.connection;
  v_n    pls_integer;
begin
  c := utl_tcp.open_connection('host.docker.internal', 2525, charset => 'AL32UTF8',
                               tx_timeout => 5);
  dbms_output.put_line('server says: ' || utl_tcp.get_line(c, remove_crlf => true));
  v_n := utl_tcp.write_line(c, 'QUIT');
  dbms_output.put_line('server says: ' || utl_tcp.get_line(c, remove_crlf => true));
  utl_tcp.close_connection(c);
end;
/

Output:

server says: 220 netlab ESMTP ready (test server, nothing is delivered)
server says: 221 2.0.0 bye

PL/SQL procedure successfully completed.

The SMTP port greets every new connection with a 220 line. The block reads it, sends QUIT, and reads the goodbye, the same exchange UTL_SMTP performs for you.

Things to Know

  • Set TX_TIMEOUT so a server that does not answer cannot block the session forever.
  • Use the character set the protocol expects; lines end with CR LF, which WRITE_LINE adds.
  • Prefer UTL_HTTP and UTL_SMTP when the protocol is HTTP or mail.

Related Guides

Conclusion

UTL_TCP opens raw TCP connections from PL/SQL for writing and reading lines or bytes. Use it for simple text protocols, set a timeout, read until END_OF_INPUT, and close the connection.

Get more Vinish.dev tutorials on Google

See my articles more often when you search Google.

Vinish Kapoor
Vinish Kapoor

An Oracle ACE, author of four books on Oracle APEX, SQL and PL/SQL, and Oracle Forms, and a software developer building Oracle database applications since 2001.

guest

0 Comments
Oldest
Newest Most Voted