Backend API. Server-side code: this runs in a Codename One backend, not in the app on the device.

public final class Tcp

  1. Object
  2. Tcp
Blocking TCP client socket for server-side (clean-target) binaries. Deliberately not com.codename1.io.Socket: that routes through CodenameOneImplementation, which a translated server binary does not have.

Methods

public static Tcp connect(String host, int port, int timeoutMillis) throws IOException
public void startTls(String host) throws IOExceptionUpgrades this connection to TLS, verifying the peer certificate against the system trust store and against host.
public void startTls(String host, String caFile) throws IOExceptionAs startTls(String), verifying against the PEM bundle at caFile INSTEAD of the system trust store.
public boolean isSecure()Whether this connection is encrypted.
public void setReadTimeout(int millis) throws IOExceptionA receive and send deadline for this connection, in milliseconds; 0 for none.
public int read(byte[] buffer, int offset, int length) throws IOExceptionReads up to length bytes.
public void write(byte[] buffer, int offset, int length) throws IOException
public void close()Closes the connection, and does not release anything an operation still holds.

Inherited methods

Method details

connect

public static Tcp connect(String host, int port, int timeoutMillis) throws IOException

startTls

public void startTls(String host) throws IOException

Upgrades this connection to TLS, verifying the peer certificate against the system trust store and against host.

An upgrade rather than a secure connect because that is the shape the database protocols need: PostgreSQL and MySQL both begin in plaintext and ask to start TLS mid-conversation, so a connect-time flag could not express it. Calling it immediately after connect gives the ordinary secure-connect behaviour.

startTls

public void startTls(String host, String caFile) throws IOException

As startTls(String), verifying against the PEM bundle at caFile INSTEAD of the system trust store.

This is what a managed database needs: RDS, Cloud SQL and the like present certificates from a private CA, and a development container presents one it generated for itself. Falling back to the system store when the named bundle fails to load would verify against roots the caller deliberately did not choose, so that is an error rather than a fallback.

isSecure

public boolean isSecure()
Whether this connection is encrypted.

setReadTimeout

public void setReadTimeout(int millis) throws IOException

A receive and send deadline for this connection, in milliseconds; 0 for none.

Set after connecting and left in place. Without one, a peer that finishes connecting and then stops answering holds the calling thread for as long as it likes – recv() on a blocking descriptor has no deadline of its own – and for a database connection that thread is a request worker, or a virtual thread’s carrier. A few stalled connections are then the whole server.

Claimed like any other operation, so a close() during it cannot hand the descriptor number to somebody else while setsockopt is looking at it.

read

public int read(byte[] buffer, int offset, int length) throws IOException
Reads up to length bytes. Returns -1 at end of stream, matching InputStream.

write

public void write(byte[] buffer, int offset, int length) throws IOException

close

public void close()

Closes the connection, and does not release anything an operation still holds.

When nothing is in flight this is the plain teardown it always was: shut the session down politely, close the descriptor, done.

When something IS in flight – the ordinary case, since close() is how a blocked read gets cancelled – the descriptor is SHUT DOWN rather than closed. That is what wakes the other thread, and it leaves the number allocated to us until that thread returns. Closing it here instead would hand the number back to the process while a read() or write() was still inside a native with it, and the next socket this process opens is given that same number: the read would then be served, silently, by an unrelated connection. The last operation out closes it for real.

close() still returns at once either way. It has to: the thread it is cancelling may be one that never comes back.