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