PrevNextUpHome SophiaFramework UNIVERSE 5.3

18.4. SFXTCPSocket Class

The SFXTCPSocket class provides functions to implement both of the TCP client and the TCP server.

In this class, it is possible to send and receive data using the stream.

In case the stream is not used, data will be sent / received using the SFXTCPSocket::Write / SFXTCPSocket::Read function.

How to use the SFXTCPSocket class as the TCP client

The TCP client can be implemented by taking the following procedures with the SFXTCPSocket class.

  1. Create the SFXTCPSocket instance, that is, the TCP socket.
  2. Open the TCP socket using the SFXTCPSocket::Open funtion.
  3. Bind the local IP address and port number to the TCP socket with the SFXTCPSocket::Bind function, if necessary. If binding is omitted, default port number will be bound to the TCP socket.
  4. Connect(or send connection request) to the TCP server using the SFXTCPSocket::Connect function.
  5. The connection result will be notified to the callback function registered with the SFXTCPSocket::Connect function.
  6. To receive data, get the input stream. When the stream is not used, data can be received with the SFXTCPSocket::Read function.
  7. To send data, get the output stream. When the stream is not used, data can be sent with the SFXTCPSocket::Write function.
  8. Step 6. and 7. are repeated until no other data needs to be sent or received.
  9. C Close the TCP socket using the SFXTCPSocket::Close function.

Reference: Network: TCP Socket Communication

Example 18.4. TCP socket communication using the stream

// The _socket variable is defined as class member variable since used in the callback function
class MyClass {
private:
    SFXTCPSocket _socket;                // SFXTCPSocket instance
    SFXAnsiStringStreamReader  _reader;  // input stream
    SFXAnsiStringStreamWriter  _writer;  // output stream
public:
    Void Start(Void);
    XALLBACK_DECLARE_SFXTCPSOCKET(OnConnect)
    XALLBACK_DECLARE_SFXANSISTRINGSTREAMREADER(OnFetch)
    XALLBACK_DECLARE_SFXANSISTRINGSTREAMWRITER(OnFlush)
};

Void MyClass::Start(Void)
{
    SFCError error;
    SFXSocketAddress host("www.example.com:80");

    // open the TCP socket
    if ((error = _socket.Open()) == SFERR_NO_ERROR) {
 
        // connect to the TCP server
        // *1. the connection result will be notified to the OnConnect function
        // *2. the host name will be automatically resolved
        error = _socket.Connect(host, XALLBACK_INTERNAL(OnConnect));
    }
    if (error != SFERR_NO_ERROR) { 

        // if an error occurs
        _socket.Close();
    }
    return;
}

// callback function notified of the connection result
XALLBACK_IMPLEMENT_SFXTCPSOCKET(MyClass, OnConnect, error)
{
    // string to send
    static AChar message[] = "GET / HTTP/1.0\r\n\r\n";

    if (error == SFERR_NO_ERROR) {

        // get the variable buffer stream for sending data
        // * the stream buffer is variable since the size argument is not specified
        if ((error = _socket.GetStreamWriter(&_writer)) == SFERR_NO_ERROR) {

            // write data from the message variable into the stream buffer
            // * the stream buffer will be expanded automatically depending on the size of data to be written
            if ((error = _writer.Write(message, lengthof(message))) == SFERR_NO_ERROR) {

                // perform flush: send data from the stream buffer to the socket actually
                // * the flush result will be notified to the OnFlush function
                error = _writer.Flush(XALLBACK_INTERNAL(OnFlush));
            }
            if (error != SFERR_NO_ERROR) { 

                // if an error occurs
                 _writer.Release();
            }
        }
    }
    if (error != SFERR_NO_ERROR) { 

       // if an error occurs
       _socket.Close();
    }
    return;
}

// callback function notified of the flush result
XALLBACK_IMPLEMENT_SFXANSISTRINGSTREAMWRITER(MyClass, OnFlush, error)
{
    // release the _writer stream since sending data has been done
    _writer.Release();

    if (error == SFERR_NO_ERROR) {

        // get the variable buffer stream for receiving data
        // * the stream buffer is variable since the size argument is not specified
        if ((error = _socket.GetStreamReader(&_reader)) == SFERR_NO_ERROR) {

            // perform fetch: receive data from the socket into the stream buffer actually
            // *1. the fetch result will be notified to the OnFetch function
            // *2. the stream buffer will be expanded automatically depending on the size of data to be received
            if ((error = _reader.Fetch(XALLBACK_INTERNAL(OnFetch))) != SFERR_NO_ERROR) {

                // if an error occurs
               _reader.Release(); 
            }
        }
    }
    if (error != SFERR_NO_ERROR) { 

        // if an error occurs
        _socket.Close();
    }
    return;
}

// callback function notified of the fetch result
XALLBACK_IMPLEMENT_SFXANSISTRINGSTREAMREADER(MyClass, OnFetch, error)
{
    SFXAnsiString string;

    if (error == SFERR_NO_ERROR) {

        // read data from the stream buffer into the string variable
        _reader > string;

        // display the content of the string variable on BREW Output Window
        TRACE("%s", string.GetCString());
    }

    // release the _reader stream since receiving data has been done
    _reader.Release();

    // close the socket
    _socket.Close();
    return;
}
[Note] TCP socket communication using the variable buffer stream

Each stream has its own buffer(stream buffer).

Since the stream for receiving from / sending to the TCP socket is gotten by calling the SFXTCPSocket::GetStreamReader / SFXTCPSocket::GetStreamWriter function with no size argument, the variable buffer will be used. Therefore, the stream buffer will be expanded to the same size with data to receive / send.

The SFXAnsiStringStreamWriter::WriteSFXAnsiString function writes data from the string variable into the stream buffer.

The SFXAnsiStringStreamReader::ReadSFXAnsiString function reads data from the stream buffer into the string variable.

The SFXStreamWriter::Flush function sends data from the stream buffer into the TCP socket.

The SFXStreamReader::Fetch function receives data from the TCP socket into the stream buffer.