Fork me on GitHub

TCP/IP Client (derived from C# to X++) [AX2012]

Solution

TCP/IP Client based on an example in my C# code. This example demonstrates how to send a string to TCP/IP Server and receive response back from it. The response is being read in batches.

The solution can be easily converted to Inbound Service.

Service data contract attribute

[DataContractAttribute]
class YourDataContract
{
    str TCPResponse;
}

Service data member attribute

[DataMemberAttribute]
public str parmTCPResponse(str _TCPResponse = TCPResponse)
{
    TCPResponse = _TCPResponse;
    return TCPResponse;
}

Class declaration

class YourClass
{
    YourDataContract                    dataContract;

    System.Net.Sockets.TcpClient        tcpClient;
    System.Net.Sockets.NetworkStream    networkStream;
    System.Byte[]                       data;
    System.TimeSpan                     maxDuration;
    System.Diagnostics.Stopwatch        sw;
    boolean                             finished;
    int                                 numberOfBytesRead;
    str                                 rb;
    System.IO.IOException               ioException;
    System.Text.Encoding                ascii;

    System.Text.StringBuilder           completeResponse;
    str                                 completeString;
}

Method

public YourDataContract connect(str _server, int _port, str _message)
{
    dataContract = new YourDataContract();
    completeResponse = new System.Text.StringBuilder();

    // Create a TcpClient.
    tcpClient = new System.Net.Sockets.TcpClient(_server, _port);

    // Set the time-out for synchronous receive methods
    tcpClient.set_ReceiveTimeout(5000);

    // Get a client stream for reading and writing.
    networkStream = tcpClient.GetStream();

    // Translate the passed message into ASCII and store it as a Byte array.
    ascii = System.Text.Encoding::get_ASCII();
    data = ascii.GetBytes(_message);

    // Send the message to the connected TcpServer.
    networkStream.Write(data, 0, data.get_Length());

    //// Receive the TcpServer.response.

    // Buffer to store the response bytes.
    data = new System.Byte[1024]();

    // Will stop after 5 seconds
    maxDuration = new System.TimeSpan(5000);
    sw = new System.Diagnostics.Stopwatch();
    sw.Start();
    finished = false;

    // Incoming message may be larger than the buffer size.
    do
    {
        try
        {
            // Read the first batch of the TcpServer response bytes.
            numberOfBytesRead = networkStream.Read(data, 0, data.get_Length());
            rb = ascii.GetString(data, 0, numberOfBytesRead);
            completeResponse.Append(rb);
            sw.Stop();
            if (sw.get_ElapsedMilliseconds() > maxDuration)
            {
                throw Exception::Timeout;
            }
            else
            {
                completeString = completeResponse.ToString();
                if (strScan(completeString, "</YourCustomeEndingTag>", 1, strLen(completeString)))
                {
                    finished = true;
                }
            }
        }
        // ToDo: Test exceptions.
        catch (Exception::CLRError)
        {
            // ToDo: Exception needs to be updated.
            info("Caught 'Exception::CLRError'.");
            ioException = CLRInterop::getLastException();
            info(ioException.ToString());
        }
    }
    while (!finished);

    dataContract.parmTCPResponse(completeResponse.ToString());

    return dataContract;
}

A Job to test

static void connect(Args _args)
{
    YourClass yourClass = new YourClass();
    str xmlMsg = ""; // Some XML string, etc.
    str xmlResponse = ""; // String to keep response received

    xmlResponse = yourClass.connect("192.168.0.15", 9555, xmlMsg).parmTCPResponse();

    info(strFmt("Data sent: %1, Data received: %2", xmlMsg, xmlResponse));
}

Comments !

links

social