= Binary Client Protocol

== Overview

Ignite binary client protocol enables user applications to communicate with an existing Ignite cluster without starting a full-fledged Ignite node. An application can connect to the cluster through a raw TCP socket. Once the connection is established, the application can communicate with the Ignite cluster and perform cache operations using the established format.

To communicate with the Ignite cluster, a client must obey the data format and communication details explained below.

== Data Format

=== Byte Ordering

Ignite binary client protocol has little-endian byte ordering.

=== Data Objects

User data, such as cache keys and values, are represented in the Ignite link:key-value-api/binary-objects[Binary Object] format. A data object can be a standard (predefined) type or a complex object. For the complete list of data types supported, see the link:binary-client-protocol/data-format[Data Format] section.

== Message Format

All messages- requests and responses, including handshake, start with an `int` type message length (excluding these first 4 bytes) followed by the payload (message body).

=== Handshake

The binary client protocol requires a connection handshake to ensure that client and server versions are compatible. The following tables show the structure of handshake message request and response. Refer to the <<Example>> section on how to send and receive a handshake request and response respectively.


[cols="1,2",opts="header"]
|===
|Request Type|   Description
|int| Length of handshake payload
|byte|    Handshake code, always 1.
|short|   Version major.
|short|   Version minor.
|short|   Version patch.
|byte|    Client code, always 2.
|String|  Username
|String|  Password
|===


[cols="1,2",opts="header"]
|===
| Response Type (success) |   Description
|int| Success message length, 1.
|byte|    Success flag, 1.
|===


[cols="1,2",opts="header"]
|===
|Response Type (failure)  |  Description
|int| Error message length.
|byte|    Success flag, 0.
|short|   Server version major.
|short|   Server version minor.
|short|   Server version patch.
|String|  Error message.
|===


=== Standard Message Header

Client operation messages are composed of a header and operation-specific data. Each operation has its own <<Client Operations,data request and response format>>, with a common header.

The following tables and examples show the request and response structure of a client operation message header:


[cols="1,2",opts="header"]
|===
|Request Type |   Description
|int| Length of payload.
|short|   Operation code
|long|    Request id, generated by client and returned as-is in response
|===


.Request header
[source, java]
----
private static void writeRequestHeader(int reqLength, short opCode, long reqId, DataOutputStream out) throws IOException {
  // Message length
  writeIntLittleEndian(10 + reqLength, out);

  // Op code
  writeShortLittleEndian(opCode, out);

  // Request id
  writeLongLittleEndian(reqId, out);
}
----


[cols="1,2",opts="header"]
|===
|Response Type | Description
|int| Length of response message.
|long|    Request id (see above)
|int| Status code (0 for success, otherwise error code)
|String|  Error message (present only when status is not 0)
|===



.Response header
[source, java]
----
private static void readResponseHeader(DataInputStream in) throws IOException {
  // Response length
  final int len = readIntLittleEndian(in);

  // Request id
  long resReqId = readLongLittleEndian(in);

  // Success code
  int statusCode = readIntLittleEndian(in);
}
----


== Connectivity

=== TCP Socket

Client applications should connect to server nodes with a TCP socket. By default, the connector is enabled on port 10800. You can configure the port number and other server-side​ connection parameters in the `clientConnectorConfiguration` property of `IgniteConfiguration` of your cluster, as shown below:

[tabs]
--
tab:XML[]

[source, xml]
----
<bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
    <!-- Thin client connection configuration. -->
    <property name="clientConnectorConfiguration">
        <bean class="org.apache.ignite.configuration.ClientConnectorConfiguration">
            <property name="host" value="127.0.0.1"/>
            <property name="port" value="10900"/>
            <property name="portRange" value="30"/>
        </bean>
    </property>

    <!-- Other Ignite Configurations. -->

</bean>

----


tab:Java[]

[source, java]
----
IgniteConfiguration cfg = new IgniteConfiguration();

ClientConnectorConfiguration ccfg = new ClientConnectorConfiguration();
ccfg.setHost("127.0.0.1");
ccfg.setPort(10900);
ccfg.setPortRange(30);

// Set client connection configuration in IgniteConfiguration
cfg.setClientConnectorConfiguration(ccfg);

// Start Ignite node
Ignition.start(cfg);
----

--

=== Connection Handshake

Besides socket connection, the thin client protocol requires a connection handshake to ensure that client and server versions are compatible. Note that handshake must be the first message after the connection is established.

For the handshake message request and response structure, see the <<Handshake>> section above.


=== Example


.Socket and Handshake Connection
[source, java]
----
Socket socket = new Socket();
socket.connect(new InetSocketAddress("127.0.0.1", 10800));

String username = "yourUsername";

String password = "yourPassword";

DataOutputStream out = new DataOutputStream(socket.getOutputStream());

// Message length
writeIntLittleEndian(18 + username.length() + password.length(), out);

// Handshake operation
writeByteLittleEndian(1, out);

// Protocol version 1.0.0
writeShortLittleEndian(1, out);
writeShortLittleEndian(1, out);
writeShortLittleEndian(0, out);

// Client code: thin client
writeByteLittleEndian(2, out);

// username
writeString(username, out);

// password
writeString(password, out);

// send request
out.flush();

// Receive handshake response
DataInputStream in = new DataInputStream(socket.getInputStream());
int length = readIntLittleEndian(in);
int successFlag = readByteLittleEndian(in);

// Since Ignite binary protocol uses little-endian byte order,
// we need to implement big-endian to little-endian
// conversion methods for write and read.

// Write int in little-endian byte order
private static void writeIntLittleEndian(int v, DataOutputStream out) throws IOException {
  out.write((v >>> 0) & 0xFF);
  out.write((v >>> 8) & 0xFF);
  out.write((v >>> 16) & 0xFF);
  out.write((v >>> 24) & 0xFF);
}

// Write short in little-endian byte order
private static final void writeShortLittleEndian(int v, DataOutputStream out) throws IOException {
  out.write((v >>> 0) & 0xFF);
  out.write((v >>> 8) & 0xFF);
}

// Write byte in little-endian byte order
private static void writeByteLittleEndian(int v, DataOutputStream out) throws IOException {
  out.writeByte(v);
}

// Read int in little-endian byte order
private static int readIntLittleEndian(DataInputStream in) throws IOException {
  int ch1 = in.read();
  int ch2 = in.read();
  int ch3 = in.read();
  int ch4 = in.read();
  if ((ch1 | ch2 | ch3 | ch4) < 0)
    throw new EOFException();
  return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0));
}


// Read byte in little-endian byte order
private static byte readByteLittleEndian(DataInputStream in) throws IOException {
  return in.readByte();
}

// Other write and read methods

----


== Client Operations

Upon successful handshake, a client can start performing various cache operations:

* link:binary-client-protocol/key-value-queries[Key-Value Queries]
* link:binary-client-protocol/sql-and-scan-queries[SQL and Scan Queries]
* link:binary-client-protocol/binary-type-metadata[Binary-Type Operations]
* link:binary-client-protocol/cache-configuration[Cache Configuration Operations]
