Backend API. Server-side code: this runs in a Codename One backend, not in the app on the device.
public final class ServerSocket
- Object
- ServerSocket
Nested types
class ServerSocket.TimeoutException | Thrown when a read or write deadline expires. |
Methods
Inherited methods
Method details
bind
public static ServerSocket bind(String host, int port, int backlog)
throws IOExceptionhost: null or “0.0.0.0” to listen on every interfaceport: 0 to let the OS choose, then askgetPort
Throws
getFd
public int getFd()getPort
public int getPort()accept
public int accept()close
public void close()setBlocking
public static void setBlocking(int fd, boolean blocking)
throws IOExceptionThrows
setTimeout
public static void setTimeout(int fd, int millis)
throws IOExceptionThrows
readIntoThreadBuffer
public static byte[] readIntoThreadBuffer(int fd, int capacity)Read from fd into this thread’s reusable buffer and return an array
whose length is exactly the number of bytes read, or null at end of stream.
On the translated target this allocates nothing and copies nothing: the array
header and its storage are C memory the collector never touches, and the
length is set per read so the caller can scan to array.length. Java SE
cannot resize an array and returns a right-sized copy instead – same
contract, different allocation accounting.
The bytes belong to the current callback on the current thread. Anything that must outlive either has to be copied out first.
threadReadBuffer
public static byte[] threadReadBuffer(int capacity)A reusable per-thread read buffer of at least capacity bytes.
The same array comes back on every call for a thread, so a server that reads through it allocates nothing per request. Its contents belong to the current callback only – the next read on this thread overwrites them, so nothing may retain it or hand it to code that might.
On the translated target the storage is a C buffer that the collector never allocated and never sweeps, so the read path contributes nothing at all to the allocation rate that paces the GC. Java SE cannot do that and returns an ordinary cached array; the observable contract is the same, which is the point – only the allocation accounting differs.
awaitReadable
public static boolean awaitReadable(int fd, int timeoutMillis)
throws IOExceptionWaits for the socket to become readable, for at most timeoutMillis. True if it is, false if the wait expired.
One syscall, and it leaves the descriptor exactly as it was. The caller uses it between requests on a keep-alive connection, where the alternatives – setting and restoring a receive deadline, or flipping to non-blocking and back – cost two to four syscalls each way and disturb the deadline that governs a real request read.
Throws
read
public static int read(int fd, byte[] buffer, int offset, int length)
throws IOExceptionThrows
write
public static void write(int fd, byte[] buffer, int offset, int length)
throws IOExceptionThrows
closeFd
public static void closeFd(int fd)setReceiveTimeout
public static void setReceiveTimeout(int fd, int millis)
throws IOExceptionThe RECEIVE deadline alone, leaving the send deadline where it is.
setTimeout sets both, which is right for a request – a peer that stops reading blocks a worker in send() just as effectively as one that stops writing. A websocket wants them apart: it is idle by design, so its read allowance is minutes or nothing at all, while a send to a peer that has stopped reading must still give up. Using setTimeout for that quietly moved the send bound from fifteen seconds to five minutes, and CN1_WS_IDLE_TIMEOUT_MS=0 removed it entirely.
Throws
shutdown
public static void shutdown(int fd)Breaks a descriptor in both directions without closing it.
For the one case a close cannot serve: a thread is parked inside a write to a peer that has stopped reading, and the connection has to go NOW. A close would free the number while that thread still holds it, and the number is reused immediately – so the write lands in whatever connection was handed it next. shutdown(2) makes the parked write fail instead, and the close follows once the writer has left.
Quiet about failure on purpose: every reason it can fail (the peer already went, the descriptor was already shut) is a state the caller wanted anyway.
peerAddress
public static byte[] peerAddress(int fd)availableProcessors
public static int availableProcessors()