SharedSocket (jTDS API)
Date: 2013-06-08

net.sourceforge.jtds.jdbc

## Class SharedSocket

- java.lang.Object
- - net.sourceforge.jtds.jdbc.SharedSocket

- Direct Known Subclasses:
    SharedLocalNamedPipe, SharedNamedPipe

       class SharedSocket
      extends java.lang.Object

  This class manages the physical connection to the SQL Server and serialises its use amongst a number of virtual sockets. This allows one physical connection to service a number of concurrent statements.

  Constraints and assumptions:

  1. Callers will not attempt to read from the server without issuing a request first.
  2. The end of a server reply can be identified as byte 2 of the header is non zero.
  Comments:
  1. This code will discard unread server data if a new request is issued. Currently the higher levels of the driver attempt to do this but may be we can just rely on this code instead.
  2. A cancel can be issued by a caller only if the server is currently sending data for the caller otherwise the cancel is ignored.
  3. Cancel packets on their own are returned as extra records appended to the previous packet so that the TdsCore module can process them.
  This version of the class will start to cache results to disk once a predetermined maximum buffer memory threshold has been passed. Small result sets that will fit within a specified limit (default 8 packets) will continue to be held in memory (even if the memory threshold has been passed) in the interests of efficiency.
  Author:
    Mike Hutchinson, Holger Rehn

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `(package private) static class` | `SharedSocket.VirtualSocket` This inner class contains the state information for the virtual socket.

  - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `private java.util.concurrent.atomic.AtomicInteger` | `_LastID` last ID assigned to a VirtualSocket instance
    `private java.util.concurrent.ConcurrentMap<java.lang.Integer,SharedSocket.VirtualSocket>` | `_VirtualSockets` Table of stream objects sharing this socket.
    `private java.io.File` | `bufferDir` The directory to buffer data to.
    `private java.lang.Object` | `cancelMonitor` Synchronization monitor for `cancelPending` and `responseOwner`.
    `private boolean` | `cancelPending` A cancel packet is pending.
    `private CharsetInfo` | `charsetInfo` The character set to use for converting strings to/from bytes.
    `private byte[]` | `doneBuffer` Buffer for TDS_DONE packets
    `private int` | `doneBufferFrag` How much of the doneBuffer has been filled with data,
    `private static int` | `globalMemUsage` Total memory usage in all instances of the driver NB.
    `private byte[]` | `hdrBuf` Buffer for packet header.
    `private java.lang.String` | `host` The server host name.
    `private java.io.DataInputStream` | `in` Input stream for network socket.
    `private int` | `maxBufSize` Current maximum input buffer size.
    `private static int` | `memoryBudget` Max memory limit to use for buffers.
    `private static int` | `minMemPkts` Minimum number of packets that will be cached in memory before the driver tries to write to disk even if memoryBudget has been exceeded.
    `private java.io.DataOutputStream` | `out` Output stream for network socket.
    `private int` | `packetCount` Count of packets received.
    `private static int` | `peakMemUsage` Peak memory usage for debug purposes.
    `private int` | `port` The server port number.
    `private SharedSocket.VirtualSocket` | `responseOwner` The virtual socket of the object that is expecting a response from the server.
    `private static boolean` | `securityViolation` Global flag to indicate that security constraints mean that attempts to create work files will fail.
    `protected int` | `serverType` The servertype one of Driver.SQLSERVER or Driver.SYBASE
    `private java.net.Socket` | `socket` The shared network socket.
    `private java.net.Socket` | `sslSocket` The shared SSL network socket;
    `private static int` | `TDS_DONE_LEN` Length of a TDS_DONE token.
    `private static int` | `TDS_DONE_TOKEN` TDS done token.
    `private static int` | `TDS_HDR_LEN` Length of TDS packet header.
    `private int` | `tdsVersion` Tds protocol version

  - ### Constructor Summary

    Constructors
    Modifier | Constructor and Description
    --- | ---
    `protected` | `SharedSocket(java.io.File bufferDir, int tdsVersion, int serverType)`
    `(package private)` | `SharedSocket(JtdsConnection connection)` Construct a `SharedSocket` object specifying host name and port.

  - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `(package private) boolean` | `cancel(SharedSocket.VirtualSocket vsock)` Send a TDS cancel packet to the server.
    `(package private) void` | `close()` Close the socket and release all resources.
    `(package private) void` | `closeStream(SharedSocket.VirtualSocket vsock)` Deallocate a stream linked to this socket.
    `private java.net.Socket` | `createSocketForJDBC3(JtdsConnection connection)` Creates a `Socket` connection.
    `private byte[]` | `dequeueInput(SharedSocket.VirtualSocket vsock)` Read a cached packet from the in memory queue or from a disk based queue.
    `(package private) void` | `disableEncryption()` Disable TLS encryption and switch back to raw TCP/IP socket.
    `(package private) void` | `enableEncryption(java.lang.String ssl)` Enable TLS encryption by creating a TLS socket over the existing TCP/IP network socket.
    `private void` | `enqueueInput(SharedSocket.VirtualSocket vsock, byte[] buffer)` Save a packet buffer in a memory queue or to a disk queue if the global memory limit for the driver has been exceeded.
    `protected void` | `finalize()` Ensure all resources are released.
    `(package private) void` | `forceClose()` Force close the socket causing any pending reads/writes to fail.
    `(package private) java.lang.String` | `getCharset()` Retrieve the character set name used to translate byte arrays to or from Strings.
    `(package private) CharsetInfo` | `getCharsetInfo()` Retrieve the character set descriptor used to translate byte arrays to or from Strings.
    `protected java.lang.String` | `getHost()` Get the server host name.
    `protected java.io.DataInputStream` | `getIn()` Getter for `in` field.
    `(package private) java.lang.String` | `getMAC()`
    `(package private) static int` | `getMemoryBudget()` Get the global buffer memory limit for all instancs of this driver.
    `(package private) static int` | `getMinMemPkts()` Get the minimum number of memory cached packets.
    `(package private) byte[]` | `getNetPacket(SharedSocket.VirtualSocket vsock, byte[] buffer)` Get a network packet.
    `protected java.io.DataOutputStream` | `getOut()` Getter for `out` field.
    `(package private) static int` | `getPktLen(byte[] buf)` Convert two bytes (in network byte order) in a byte array into a Java short integer.
    `protected int` | `getPort()` Get the server port number.
    `(package private) RequestStream` | `getRequestStream(int bufferSize, int maxPrecision)` Obtain an instance of a server request stream for this socket.
    `(package private) ResponseStream` | `getResponseStream(RequestStream requestStream, int bufferSize)` Obtain an instance of a server response stream for this socket.
    `(package private) int` | `getTdsVersion()` Retrieve the TDS version that is active on the connection supported by this socket.
    `(package private) boolean` | `isConnected()` Get the connected status of this socket.
    `private byte[]` | `readPacket(byte[] buffer)` Read a physical TDS packet from the network.
    `(package private) byte[]` | `sendNetPacket(SharedSocket.VirtualSocket vsock, byte[] buffer)` Send a network packet.
    `(package private) void` | `setCharsetInfo(CharsetInfo charsetInfo)` Set the character set descriptor to be used to translate byte arrays to or from Strings.
    `protected void` | `setIn(java.io.DataInputStream in)` Setter for `in` field.
    `protected void` | `setKeepAlive(boolean keepAlive)` Set the socket keep alive.
    `(package private) static void` | `setMemoryBudget(int memoryBudget)` Set the global buffer memory limit for all instances of this driver.
    `(package private) static void` | `setMinMemPkts(int minMemPkts)` Set the minimum number of packets to cache in memory before writing to disk.
    `protected void` | `setOut(java.io.DataOutputStream out)` Setter for `out` field.
    `protected void` | `setTdsVersion(int tdsVersion)` Set the TDS version field.
    `protected void` | `setTimeout(int timeout)` Set the socket timeout.

    - ### Methods inherited from class java.lang.Object

      `clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Field Detail

    - #### socket

          private java.net.Socket socket

      The shared network socket.

    - #### sslSocket

          private java.net.Socket sslSocket

      The shared SSL network socket;

    - #### out

          private java.io.DataOutputStream out

      Output stream for network socket.

    - #### in

          private java.io.DataInputStream in

      Input stream for network socket.

    - #### maxBufSize

          private int maxBufSize

      Current maximum input buffer size.

    - #### _LastID

          private final java.util.concurrent.atomic.AtomicInteger _LastID

      last ID assigned to a VirtualSocket instance

    - #### _VirtualSockets

          private final java.util.concurrent.ConcurrentMap<java.lang.Integer,SharedSocket.VirtualSocket> _VirtualSockets

      Table of stream objects sharing this socket.

    - #### responseOwner

          private SharedSocket.VirtualSocket responseOwner

      The virtual socket of the object that is expecting a response from the server.

    - #### hdrBuf

          private final byte[] hdrBuf

      Buffer for packet header.

    - #### bufferDir

          private final java.io.File bufferDir

      The directory to buffer data to.

    - #### globalMemUsage

          private static int globalMemUsage

      Total memory usage in all instances of the driver NB. Access to this field should probably be synchronized but in practice lost updates will not matter much and I think all VMs tend to do atomic saves to integer variables.

    - #### peakMemUsage

          private static int peakMemUsage

      Peak memory usage for debug purposes.

    - #### memoryBudget

          private static int memoryBudget

      Max memory limit to use for buffers. Only when this limit is exceeded will the driver start caching to disk.

    - #### minMemPkts

          private static int minMemPkts

      Minimum number of packets that will be cached in memory before the driver tries to write to disk even if memoryBudget has been exceeded.

    - #### securityViolation

          private static boolean securityViolation

      Global flag to indicate that security constraints mean that attempts to create work files will fail.

    - #### tdsVersion

          private int tdsVersion

      Tds protocol version

    - #### serverType

          protected final int serverType

      The servertype one of Driver.SQLSERVER or Driver.SYBASE

    - #### charsetInfo

          private CharsetInfo charsetInfo

      The character set to use for converting strings to/from bytes.

    - #### packetCount

          private int packetCount

      Count of packets received.

    - #### host

          private java.lang.String host

      The server host name.

    - #### port

          private int port

      The server port number.

    - #### cancelPending

          private boolean cancelPending

      A cancel packet is pending.

    - #### cancelMonitor

          private final java.lang.Object cancelMonitor

      Synchronization monitor for `cancelPending` and `responseOwner`.

    - #### doneBuffer

          private final byte[] doneBuffer

      Buffer for TDS_DONE packets

    - #### doneBufferFrag

          private int doneBufferFrag

      How much of the doneBuffer has been filled with data,

    - #### TDS_DONE_TOKEN

          private static final int TDS_DONE_TOKEN

      TDS done token.
      See Also:
        Constant Field Values

    - #### TDS_DONE_LEN

          private static final int TDS_DONE_LEN

      Length of a TDS_DONE token.
      See Also:
        Constant Field Values

    - #### TDS_HDR_LEN

          private static final int TDS_HDR_LEN

      Length of TDS packet header.
      See Also:
        Constant Field Values

  - ### Constructor Detail

    - #### SharedSocket

          protected SharedSocket(java.io.File bufferDir,
                      int tdsVersion,
                      int serverType)

    - #### SharedSocket

          SharedSocket(JtdsConnection connection)
                 throws java.io.IOException,
                        java.net.UnknownHostException

      Construct a `SharedSocket` object specifying host name and port.
      Parameters:
        `connection` - the connection object
      Throws:
        `java.io.IOException` - if socket open fails
        `java.net.UnknownHostException`

  - ### Method Detail

    - #### createSocketForJDBC3

          private java.net.Socket createSocketForJDBC3(JtdsConnection connection)
                                                throws java.io.IOException

      Creates a `Socket` connection.
      Parameters:
        `connection` - the connection object
      Returns:
        a socket open to the host and port with the given timeout
      Throws:
        `java.io.IOException` - if socket open fails

    - #### getMAC

          java.lang.String getMAC()

    - #### enableEncryption

          void enableEncryption(java.lang.String ssl)
                          throws java.io.IOException

      Enable TLS encryption by creating a TLS socket over the existing TCP/IP network socket.
      Parameters:
        `ssl` - the SSL URL property value
      Throws:
        `java.io.IOException` - if an I/O error occurs

    - #### disableEncryption

          void disableEncryption()
                           throws java.io.IOException

      Disable TLS encryption and switch back to raw TCP/IP socket.
      Throws:
        `java.io.IOException` - if an I/O error occurs

    - #### setCharsetInfo

          void setCharsetInfo(CharsetInfo charsetInfo)

      Set the character set descriptor to be used to translate byte arrays to or from Strings.
      Parameters:
        `charsetInfo` - the character set descriptor

    - #### getCharsetInfo

          CharsetInfo getCharsetInfo()

      Retrieve the character set descriptor used to translate byte arrays to or from Strings.

    - #### getCharset

          java.lang.String getCharset()

      Retrieve the character set name used to translate byte arrays to or from Strings.
      Returns:
        the character set name as a `String`

    - #### getRequestStream

          RequestStream getRequestStream(int bufferSize,
                                       int maxPrecision)

      Obtain an instance of a server request stream for this socket.
      Parameters:
        `bufferSize` - the initial buffer size to be used by the `RequestStream`
        `maxPrecision` - the maximum precision for numeric/decimal types
      Returns:
        the server request stream as a `RequestStream`

    - #### getResponseStream

          ResponseStream getResponseStream(RequestStream requestStream,
                                         int bufferSize)

      Obtain an instance of a server response stream for this socket. NB. getRequestStream() must be used first to obtain the RequestStream needed as a parameter for this method.
      Parameters:
        `requestStream` - an existing server request stream object obtained from this `SharedSocket`
        `bufferSize` - the initial buffer size to be used by the `RequestStream`
      Returns:
        the server response stream as a `ResponseStream`

    - #### getTdsVersion

          int getTdsVersion()

      Retrieve the TDS version that is active on the connection supported by this socket.
      Returns:
        the TDS version as an `int`

    - #### setTdsVersion

          protected void setTdsVersion(int tdsVersion)

      Set the TDS version field.
      Parameters:
        `tdsVersion` - the TDS version as an `int`

    - #### setMemoryBudget

          static void setMemoryBudget(int memoryBudget)

      Set the global buffer memory limit for all instances of this driver.
      Parameters:
        `memoryBudget` - the global memory budget

    - #### getMemoryBudget

          static int getMemoryBudget()

      Get the global buffer memory limit for all instancs of this driver.
      Returns:
        the memory limit as an `int`

    - #### setMinMemPkts

          static void setMinMemPkts(int minMemPkts)

      Set the minimum number of packets to cache in memory before writing to disk.
      Parameters:
        `minMemPkts` - the minimum number of packets to cache

    - #### getMinMemPkts

          static int getMinMemPkts()

      Get the minimum number of memory cached packets.
      Returns:
        minimum memory packets as an `int`

    - #### isConnected

          boolean isConnected()

      Get the connected status of this socket.
      Returns:
        `true` if the underlying socket is connected

    - #### cancel

          boolean cancel(SharedSocket.VirtualSocket vsock)

      Send a TDS cancel packet to the server.
      Parameters:
        `vsock` - the `SharedSocket.VirtualSocket` used by the request to be canceled
      Returns:
        `true` if a cancel is actually issued by this method call

    - #### close

          void close()
               throws java.io.IOException

      Close the socket and release all resources.
      Throws:
        `java.io.IOException` - if the socket close fails

    - #### forceClose

          void forceClose()

      Force close the socket causing any pending reads/writes to fail.

      Used by the login timer to abort a login attempt.

    - #### closeStream

          void closeStream(SharedSocket.VirtualSocket vsock)

      Deallocate a stream linked to this socket.
      Parameters:
        `vsock` - the `SharedSocket.VirtualSocket` to close

    - #### sendNetPacket

          byte[] sendNetPacket(SharedSocket.VirtualSocket vsock,
                             byte[] buffer)
                         throws java.io.IOException

      Send a network packet. If output for another virtual socket is in progress this packet will be sent later.
      Parameters:
        `vsock` - `SharedSocket.VirtualSocket` of the originating `RequestStream`
        `buffer` - the data to send
      Returns:
        the same buffer received if emptied or another buffer w/ the same size if the incoming buffer is cached (to avoid copying)
      Throws:
        `java.io.IOException` - if an I/O error occurs

    - #### getNetPacket

          byte[] getNetPacket(SharedSocket.VirtualSocket vsock,
                            byte[] buffer)
                        throws java.io.IOException

      Get a network packet. This may be read from the network directly or from previously cached buffers.
      Parameters:
        `vsock` - `SharedSocket.VirtualSocket` the originating ResponseStream object
        `buffer` - the data buffer to receive the object (may be replaced)
      Returns:
        the data in a `byte[]` buffer
      Throws:
        `java.io.IOException` - if an I/O error occurs

    - #### enqueueInput

          private void enqueueInput(SharedSocket.VirtualSocket vsock,
                          byte[] buffer)
                             throws java.io.IOException

      Save a packet buffer in a memory queue or to a disk queue if the global memory limit for the driver has been exceeded.
      Parameters:
        `vsock` - the virtual socket owning this data
        `buffer` - the data to queue
      Throws:
        `java.io.IOException`

    - #### dequeueInput

          private byte[] dequeueInput(SharedSocket.VirtualSocket vsock)
                               throws java.io.IOException

      Read a cached packet from the in memory queue or from a disk based queue.
      Parameters:
        `vsock` - the virtual socket owning this data
      Returns:
        a buffer containing the packet
      Throws:
        `java.io.IOException`

    - #### readPacket

          private byte[] readPacket(byte[] buffer)
                             throws java.io.IOException

      Read a physical TDS packet from the network.
      Parameters:
        `buffer` - a buffer to read the data into (if it fits) or null
      Returns:
        either the incoming buffer if it was large enough or a newly allocated buffer with the read packet
      Throws:
        `java.io.IOException`

    - #### getPktLen

          static int getPktLen(byte[] buf)

      Convert two bytes (in network byte order) in a byte array into a Java short integer.
      Parameters:
        `buf` - array of data
      Returns:
        the 16 bit unsigned value as an `int`

    - #### setTimeout

          protected void setTimeout(int timeout)
                             throws java.net.SocketException

      Set the socket timeout.
      Parameters:
        `timeout` - the timeout value in milliseconds
      Throws:
        `java.net.SocketException`

    - #### setKeepAlive

          protected void setKeepAlive(boolean keepAlive)
                               throws java.net.SocketException

      Set the socket keep alive.
      Parameters:
        `keepAlive` - `true` to turn on socket keep alive
      Throws:
        `java.net.SocketException`

    - #### getIn

          protected java.io.DataInputStream getIn()

      Getter for `in` field.
      Returns:
        `InputStream` used for communication

    - #### setIn

          protected void setIn(java.io.DataInputStream in)

      Setter for `in` field.
      Parameters:
        `in` - the `InputStream` to be used for communication

    - #### getOut

          protected java.io.DataOutputStream getOut()

      Getter for `out` field.
      Returns:
        `OutputStream` used for communication

    - #### setOut

          protected void setOut(java.io.DataOutputStream out)

      Setter for `out` field.
      Parameters:
        `out` - the `OutputStream` to be used for communication

    - #### getHost

          protected java.lang.String getHost()

      Get the server host name.
      Returns:
        the host name as a `String`

    - #### getPort

          protected int getPort()

      Get the server port number.
      Returns:
        the host port as an `int`

    - #### finalize

          protected void finalize()
                           throws java.lang.Throwable

      Ensure all resources are released.
      Overrides:
        `finalize` in class `java.lang.Object`
      Throws:
        `java.lang.Throwable`

Generated on June 8 2013