Backend API. Server-side code: this runs in a Codename One backend, not in the app on the device.
public final class Tcp
- Object
- Tcp
Methods
public static Tcp connect(String host, int port, int timeoutMillis)
throws IOException | |
public void startTls(String host)
throws IOException | Upgrades this connection to TLS, verifying the peer certificate against the system trust store and against host. |
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. |
public boolean isSecure() | Whether this connection is encrypted. |
public void setReadTimeout(int millis)
throws IOException | A receive and send deadline for this connection, in milliseconds; 0 for none. |
public int read(byte[] buffer, int offset, int length)
throws IOException | Reads 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 IOExceptionThrows
startTls
public void startTls(String host)
throws IOExceptionUpgrades 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.
Throws
startTls
public void startTls(String host, String caFile)
throws IOExceptionAs 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.
Throws
isSecure
public boolean isSecure()setReadTimeout
public void setReadTimeout(int millis)
throws IOExceptionA 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.
Throws
read
public int read(byte[] buffer, int offset, int length)
throws IOExceptionThrows
write
public void write(byte[] buffer, int offset, int length)
throws IOExceptionThrows
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.