Membangun Sistem Jaringan Komunikasi dengan Qt dan TCP/IP

Membangun Sistem Jaringan Komunikasi dengan Qt dan TCP/IP

Dalam artikel ini, kita akan membahas bagaimana kita dapat membangun sistem jaringan komunikasi menggunakan Qt dan teknologi TCP/IP. Kita akan membuat sebuah aplikasi server yang dapat menerima data dari beberapa sumber dan mengirimkannya ke berbagai tujuan.

Struktur Aplikasi

Aplikasi server yang kita buat disini memiliki struktur sebagai berikut:

class Server : public QMainWindow {
public:
 Server(QWidget *parent);
 ~Server();

private slots:
 void newConnection();
 void disconnected();
 void readyRead();

private:
 QTcpServer *server;
 QHash<QTcpSocket*, QByteArray*> buffers; // buffer untuk menyimpan data hingga blok terreceive
 QHash<QTcpSocket*, qint32*> sizes; // untuk menyimpan ukuran blok agar dapat diperiksa apakah blok telah diterima dengan lengkap

 static inline qint32 ArrayToInt(QByteArray source);
};

Dalam aplikasi ini, kita memiliki sebuah objek Server yang mengextends dari kelas QMainWindow. Aplikasi ini memiliki beberapa slot, yaitu newConnection(), disconnected(), dan readyRead(). Slot-slot ini digunakan untuk berkomunikasi dengan koneksi-koneksi TCP/IP yang tersedia.

Konstruktor

Dalam konstruktor aplikasi, kita membuat objek QTcpServer dan menghubungkannya ke slot newConnection():

Server::Server(QWidget *parent) : QMainWindow(parent), ui(new Ui::Server) {
 ui->setupUi(this);
 server = new QTcpServer(this);
 connect(server, SIGNAL(newConnection()), this, SLOT(newConnection()));
}

Kemudian, kita membuat sebuah string yang berisi informasi tentang apakah aplikasi sedang menyambung ke port 1024 atau tidak:

QString socket_data;
socket_data.sprintf("Listening: %s\n", server->listen(QHostAddress::Any, 1024) ? "true" : "false");
ui->textBrowser->insertPlainText(socket_data);

Slot newConnection()

Dalam slot newConnection(), kita akan membuat sebuah objek QTcpSocket dan menghubungkannya ke beberapa slot lainnya:

void Server::newConnection() {
 while (server->hasPendingConnections()) {
 QTcpSocket *socket = server->nextPendingConnection();
 connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
 connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
 QByteArray *buffer = new QByteArray();
 qint32 *s = new qint32(0);
 buffers.insert(socket, buffer);
 sizes.insert(socket, s);
 }
}

Slot disconnected()

Dalam slot disconnected(), kita akan memproses objek QTcpSocket yang telah terhubung dan menghapus semua data yang terkait dengan socket tersebut:

void Server::disconnected() {
 QTcpSocket *socket = static_cast<QTcpSocket*>(sender());
 QByteArray *buffer = buffers.value(socket);
 qint32 *s = sizes.value(socket);
 socket->deleteLater();
 delete buffer;
 delete s;
}

Slot readyRead()

Dalam slot readyRead(), kita akan memproses data yang telah diterima oleh socket dan menghapus semua data yang terkait dengan socket tersebut:

void Server::readyRead() {
 QTcpSocket *socket = static_cast<QTcpSocket*>(sender());
 QByteArray *buffer = buffers.value(socket);
 qint32 *s = sizes.value(socket);
 qint32 size = *s;
 while (socket->bytesAvailable() > 0) {
 buffer->append(socket->readAll());
 }
 while ((size == 0 && buffer->size() >= 4) || (size > 0 && buffer->size() >= size)) {
 // Sementara kita dapat memproses data, maka kita akan memprosesnya
 if (size == 0 && buffer->size() >= 4) {
 // Jika ukuran data telah diterima dengan lengkap, maka kita akan menyimpannya ke dalam variabel global
 size = ArrayToInt(buffer->mid(0, 4));
 *s = size;
 buffer->remove(0, 4);
 } else if (size > 0 && buffer->size() >= size) {
 // Jika data telah diterima dengan lengkap, maka kita akan mengirimkannya ke tujuan
 ui->textBrowser->insertPlainText(QString(buffer->data()));
 QByteArray data = buffer->mid(0, size);
 // Kita dapat mengirimkan data ini ke tujuan yang diinginkan
 }
 }
}

Fungsi ArrayToInt()

Fungsi ArrayToInt() digunakan untuk mengonversi sebuah array byte menjadi sebuah nilai integer:

static inline qint32 ArrayToInt(QByteArray source) {
 qint32 result = 0;
 for (int i = 0; i < source.size(); i++) {
 result |= static_cast<quint8>(source[i]) << (i * 8);
 }
 return result;
}

Dalam artikel ini, kita telah membahas bagaimana kita dapat membangun sebuah aplikasi server yang dapat menerima data dari beberapa sumber dan mengirimkannya ke berbagai tujuan. Aplikasi ini menggunakan teknologi TCP/IP dan Qt untuk membuat koneksi-koneksi jaringan. Kita juga telah membahas tentang beberapa slot yang digunakan untuk berkomunikasi dengan koneksi-koneksi jaringan.

Penutup

Dalam artikel ini, kita telah membangun sebuah aplikasi server yang dapat menerima data dari beberapa sumber dan mengirimkannya ke berbagai tujuan. Aplikasi ini menggunakan teknologi TCP/IP dan Qt untuk membuat koneksi-koneksi jaringan. Kita juga telah membahas tentang beberapa slot yang digunakan untuk berkomunikasi dengan koneksi-koneksi jaringan. Aplikasi server ini dapat dipakai dalam berbagai situasi, seperti komunikasi data antara perangkat-perangkat di jaringan.

Daftar Pustaka

[1] Qt Documentation: https://doc.qt.io/qt-5/
[2] TCP/IP Tutorial: http://www.tutorialspoint.com/tcpip/index.htm