// This is the client implementation for the TCP socket with the attached callback service. Callback service is optional.
import ballerina/io;
import ballerina/socket;

public function main() {
    // Create a new socket client by providing the host, port, and callback service.
    socket:Client socketClient = new ({
        host: "localhost",
        port: 61598
    });
    string content = "Hello Ballerina";
    byte[] payloadByte = content.toBytes();
    // Send desired content to the server using the write function.
    int i = 0;
    int arrayLength = payloadByte.length();
    while (i < arrayLength) {
        var writeResult = socketClient->write(payloadByte);
        if (writeResult is error) {
            io:println("Unable to written the content ", writeResult);
        } else {
            i = i + writeResult;
            payloadByte = payloadByte.slice(writeResult, arrayLength);
        }
    }
    // Reading response from the server.
    var result = socketClient->read();
    if (result is [byte[], int]) {
        var [reply, length] = result;
        if (length > 0) {
            var byteChannel =
            io:createReadableChannel(reply);
            if (byteChannel is io:ReadableByteChannel) {
                io:ReadableCharacterChannel characterChannel =
                new io:ReadableCharacterChannel(byteChannel, "UTF-8");
                var str = characterChannel.read(25);
                if (str is string) {
                    io:println(<@untainted>str);
                } else {
                    io:println("Error while reading characters ", str);
                }
            } else {
                io:println("Client close: ", socketClient.remotePort);
            }
        }
    } else {
        io:println(result);
    }

    // Close the connection between the server and the client.
    var closeResult = socketClient->close();
    if (closeResult is error) {
        io:println(closeResult);
    } else {
        io:println("Client connection closed successfully.");
    }
}

// This is the server implementation for the TCP socket.
import ballerina/io;
import ballerina/log;
import ballerina/socket;

// Bind the service to the port.
// The socket listener should have these four predefined resources.
service echoServer on new socket:Listener(61598) {
    // This resource is invoked when the new client joins.
    resource function onConnect(socket:Caller caller) {
        log:printInfo("Client connected: " + caller.id.toString());
    }

    // This resource is invoked once the content is received from the client.
    resource function onReadReady(socket:Caller caller) {
        var result = caller->read();
        if (result is [byte[], int]) {
            var [content, length] = result;
            if (length > 0) {
                // Create a new `ReadableByteChannel` using the newly received content.
                var byteChannel =
                io:createReadableChannel(content);
                if (byteChannel is io:ReadableByteChannel) {
                    io:ReadableCharacterChannel characterChannel =
                    new io:ReadableCharacterChannel(byteChannel, "UTF-8");
                    var str = characterChannel.read(20);
                    if (str is string) {
                        string reply = <@untainted>str + " back";
                        byte[] payloadByte = reply.toBytes();
                        // Send the reply to the `caller`.
                        int i = 0;
                        int arrayLength = payloadByte.length();
                        while (i < arrayLength) {
                            var writeResult = caller->write(payloadByte);
                            if (writeResult is int) {
                                log:printInfo("Number of bytes written: "
                                    + writeResult.toString());
                                i = i + writeResult;
                                payloadByte = payloadByte.slice(writeResult, arrayLength);
                            } else {
                                log:printError("Unable to write the content",
                                    writeResult);
                            }
                        }
                    } else {
                        log:printError("Error while writing content to the caller",
                            str);
                    }
                }
            } else {
                log:printInfo("Client left: " + caller.id.toString());
            }
        } else {
            io:println(result);
        }
    }

    // This resource is invoked for the error situation
    // if it happens during the `onConnect` and `onReadReady`.
    resource function onError(socket:Caller caller, error er) {
        log:printError("An error occurred", er);
    }
}

Basic TCP Socket

The TCP Listener is used to expose TCP service over the TCP protocol. The TCP Client is used to connect to a remote TCP server. This sample demonstrates how the TCP socket listener service interacts with the TCP client.

import ballerina/io;
import ballerina/socket;

This is the client implementation for the TCP socket with the attached callback service. Callback service is optional.

public function main() {
    socket:Client socketClient = new ({
        host: "localhost",
        port: 61598
    });
    string content = "Hello Ballerina";
    byte[] payloadByte = content.toBytes();

Create a new socket client by providing the host, port, and callback service.

    int i = 0;
    int arrayLength = payloadByte.length();
    while (i < arrayLength) {
        var writeResult = socketClient->write(payloadByte);
        if (writeResult is error) {
            io:println("Unable to written the content ", writeResult);
        } else {
            i = i + writeResult;
            payloadByte = payloadByte.slice(writeResult, arrayLength);
        }
    }

Send desired content to the server using the write function.

    var result = socketClient->read();
    if (result is [byte[], int]) {
        var [reply, length] = result;
        if (length > 0) {
            var byteChannel =
            io:createReadableChannel(reply);
            if (byteChannel is io:ReadableByteChannel) {
                io:ReadableCharacterChannel characterChannel =
                new io:ReadableCharacterChannel(byteChannel, "UTF-8");
                var str = characterChannel.read(25);
                if (str is string) {
                    io:println(<@untainted>str);
                } else {
                    io:println("Error while reading characters ", str);
                }
            } else {
                io:println("Client close: ", socketClient.remotePort);
            }
        }
    } else {
        io:println(result);
    }

Reading response from the server.

    var closeResult = socketClient->close();
    if (closeResult is error) {
        io:println(closeResult);
    } else {
        io:println("Client connection closed successfully.");
    }
}

Close the connection between the server and the client.

# To run the client, navigate to the directory that contains the
# `.bal` file and use the `ballerina run` command below.
ballerina run tcp_socket_client.bal
# Print the response that is obtained from the server.
Hello Ballerina back
Client connection closed successfully.
import ballerina/io;
import ballerina/log;
import ballerina/socket;

This is the server implementation for the TCP socket.

service echoServer on new socket:Listener(61598) {

Bind the service to the port. The socket listener should have these four predefined resources.

    resource function onConnect(socket:Caller caller) {
        log:printInfo("Client connected: " + caller.id.toString());
    }

This resource is invoked when the new client joins.

    resource function onReadReady(socket:Caller caller) {
        var result = caller->read();
        if (result is [byte[], int]) {
            var [content, length] = result;
            if (length > 0) {

This resource is invoked once the content is received from the client.

                var byteChannel =
                io:createReadableChannel(content);
                if (byteChannel is io:ReadableByteChannel) {
                    io:ReadableCharacterChannel characterChannel =
                    new io:ReadableCharacterChannel(byteChannel, "UTF-8");
                    var str = characterChannel.read(20);
                    if (str is string) {
                        string reply = <@untainted>str + " back";
                        byte[] payloadByte = reply.toBytes();

Create a new ReadableByteChannel using the newly received content.

                        int i = 0;
                        int arrayLength = payloadByte.length();
                        while (i < arrayLength) {
                            var writeResult = caller->write(payloadByte);
                            if (writeResult is int) {
                                log:printInfo("Number of bytes written: "
                                    + writeResult.toString());
                                i = i + writeResult;
                                payloadByte = payloadByte.slice(writeResult, arrayLength);
                            } else {
                                log:printError("Unable to write the content",
                                    writeResult);
                            }
                        }
                    } else {
                        log:printError("Error while writing content to the caller",
                            str);
                    }
                }
            } else {
                log:printInfo("Client left: " + caller.id.toString());
            }
        } else {
            io:println(result);
        }
    }

Send the reply to the caller.

    resource function onError(socket:Caller caller, error er) {
        log:printError("An error occurred", er);
    }
}

This resource is invoked for the error situation if it happens during the onConnect and onReadReady.

# To start the service, navigate to the directory that contains the
# `.bal` file and use the `ballerina run` command below.
ballerina run tcp_socket_listener.bal
# The socket listener starts listening to the port 61598 for incoming client requests.
[ballerina/socket] started socket listener 61598
2019-02-18 11:24:32,429 INFO  [] - Client connected: 504372137
2019-02-18 11:24:32,467 INFO  [] - Number of bytes written: 20
2019-02-18 11:24:32,487 INFO  [] - Client left: 504372137