Class ServerSocket

java.lang.Object
com.codename1.backend.ServerSocket

public final class ServerSocket extends Object
A listening TCP socket and the blocking read/write a worker uses once it owns a connection. Deliberately fd-based rather than object-per-socket: the reactor deals in descriptors and an extra object per idle connection is exactly the cost this design exists to avoid.
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static final class 
    Thrown when a read or write deadline expires.
  • Method Summary

    Modifier and Type
    Method
    Description
    int
    The accepted descriptor, or -1 when nothing was waiting.
    static int
    Cores available to this process.
    static boolean
    awaitReadable(int fd, int timeoutMillis)
    Waits for the socket to become readable, for at most timeoutMillis.
    bind(String host, int port, int backlog)
    • host: null or "0.0.0.0" to listen on every interface
    void
     
    static void
    closeFd(int fd)
     
    int
     
    int
     
    static int
    read(int fd, byte[] buffer, int offset, int length)
    -1 at end of stream, as InputStream does.
    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.
    static void
    setBlocking(int fd, boolean blocking)
    Blocking or non-blocking mode for one descriptor.
    static void
    setReceiveTimeout(int fd, int millis)
    The RECEIVE deadline alone, leaving the send deadline where it is.
    static void
    setTimeout(int fd, int millis)
    Applies a receive and send deadline.
    static void
    shutdown(int fd)
    Breaks a descriptor in both directions without closing it.
    static byte[]
    threadReadBuffer(int capacity)
    A reusable per-thread read buffer of at least capacity bytes.
    static void
    write(int fd, byte[] buffer, int offset, int length)
     

    Methods inherited from class Object

    clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • bind

      public static ServerSocket bind(String host, int port, int backlog) throws IOException
      • host: null or "0.0.0.0" to listen on every interface
      • port: 0 to let the OS choose, then ask getPort()
      Throws:
      IOException
    • getFd

      public int getFd()
    • getPort

      public int getPort()
    • accept

      public int accept()
      The accepted descriptor, or -1 when nothing was waiting.
    • close

      public void close()
    • setBlocking

      public static void setBlocking(int fd, boolean blocking) throws IOException
      Blocking or non-blocking mode for one descriptor. The reactor needs non-blocking; a worker that owns a connection wants blocking, so it can read a request without a state machine.
      Throws:
      IOException
    • setTimeout

      public static void setTimeout(int fd, int millis) throws IOException
      Applies a receive and send deadline. Without one a connection that opens and says nothing holds a worker forever, and the pool is bounded.
      Throws:
      IOException
    • 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 IOException

      Waits 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:
      IOException
    • read

      public static int read(int fd, byte[] buffer, int offset, int length) throws IOException
      -1 at end of stream, as InputStream does.
      Throws:
      IOException
    • write

      public static void write(int fd, byte[] buffer, int offset, int length) throws IOException
      Throws:
      IOException
    • closeFd

      public static void closeFd(int fd)
    • setReceiveTimeout

      public static void setReceiveTimeout(int fd, int millis) throws IOException

      The 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:
      IOException
    • 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.

    • availableProcessors

      public static int availableProcessors()
      Cores available to this process.