C++ QT Project Recommendation – WeChat-like Chat Application with Linux C++ Backend

1 Project Overview

The client is developed using QT6, and the backend is implemented in Linux C++. It provides users with an instant messaging platform.

Project Address: https://gitee.com/voice-of-sentiment/chat-forge.git

Video explanation and source code access:

https://www.bilibili.com/video/BV16UYMztEoz/

C++ QT Project Recommendation - WeChat-like Chat Application with Linux C++ Backend

2 Compiling and Running the Linux C++ Backend

Open-source project address

git clone    https://gitee.com/voice-of-sentiment/chat-forge.gitcd chat-forge/server/thirdpartygit clone https://gitee.com/NEU-lab/SQLiteCpp.git# If using the source code provided by Lao Liao, just unzip the source package# Return to chat-forge/server directorycd ..cd buildrm -rf *# Re-run cmake to compile in debug modecmake -DCMAKE_BUILD_TYPE=Debug ..make -j4

After successful compilation, the server executable file will be generated.

Run:

./server

The default listening port is: 8888

3 Compiling and Running the QT Client

Compilation environment: QT6.5 MinGW 64-bit

Before running the code, modify the server’s IP address and port.

C++ QT Project Recommendation - WeChat-like Chat Application with Linux C++ Backend

Account registration must use numbers:

C++ QT Project Recommendation - WeChat-like Chat Application with Linux C++ Backend

Then open another client

The usage is very simple: in the command line provided by Qt, run windeployqt to copy the required Qt plugins/DLLs to the same directory.

Steps

  • Open the “Qt 6.5.0 for Desktop (MinGW 64-bit)” command prompt (ensure windeployqt is in PATH).

  • Navigate to your exe directory:

# First switch the driveF:# Navigate to the specific pathcd  F:\0voice\vip\tc\202412\build-OurChat-Desktop_Qt_6_5_0_MinGW_64_bit-Debug\debug
  • Execute deployment (Debug build):

windeployqt --verbose 2 --no-translations OurChat.exe
  • If it is a Release build, enter the release directory and execute:

windeployqt --release --verbose 2 --no-translations OurChat.exe
  • After execution, the exe directory should contain platforms\qwindows.dllstyles\…imageformats\… and multiple Qt6*.dll files.

  • Double-click OurChat.exe to start; if prompted for missing DLLs, it is likely that the MinGW runtime library has not been copied or Debug/Release libraries have been mixed.

4 Detailed Architecture of the Linux Backend

4.1 Overall Architecture of the Server

The server adopts amultithreading + session management + command dispatch architecture model, allocating an independent processing thread for each client connection.

Core Component Description

C++ QT Project Recommendation - WeChat-like Chat Application with Linux C++ Backend

Thread Model

The server uses aone connection one thread model:

  • The main thread is responsible for listening and accepting connections

  • An independent worker thread is allocated for each client connection

  • Threads protect shared resources through mutexes

Architecture Flowchart

C++ QT Project Recommendation - WeChat-like Chat Application with Linux C++ Backend

4.2 Network Communication Protocol

Message Format Design

Useslength prefix + JSON message body binary protocol:

[0-3 bytes]    [4 bytes start] message length     JSON message body (4 bytes)      (variable length)

Protocol Implementation Details

Message Sending Process:

  • Serialize the JSON object to a string

  • Calculate the message length (in bytes)

  • Construct 4-byte length header + JSON message body

  • Send the complete data packet through the socket

Message Receiving Process:

  • First read 4 bytes to get the message length

  • Read the complete JSON data according to the length

  • Parse the JSON and dispatch to the corresponding handler function

// Example send codevoid Session::sendMsg(json &j) {    std::string msg = j.dump();    int len = msg.length();    char buffer[4];    memcpy(buffer, &len, sizeof(len));
    char *message = new char[4 + len];    memcpy(message, buffer, 4);           // Length header    memcpy(message + 4, msg.c_str(), len); // JSON body
    send(m_socket, message, len + 4, 0);}

4.3 Database Design

Detailed Description of Data Tables

C++ QT Project Recommendation - WeChat-like Chat Application with Linux C++ Backend

Database ER Relationship Diagram

C++ QT Project Recommendation - WeChat-like Chat Application with Linux C++ Backend

Key Design Features

  • User account auto-increment: The account field auto-increments to ensure uniqueness

  • Bidirectional friend relationship: The friend table stores friend relationships through a composite primary key (user1, user2)

  • Group hierarchy management: The group owner is associated with the user table through the group_master field

  • Group nickname support: Members can have different nicknames in different groups

4.4 Command System Details

Command Enumeration Definition

enum commands {    cmd_regist = 0,              // User registration    cmd_login,                   // User login      cmd_logout,                  // User logout    cmd_friend_search,           // Search for friends    cmd_add_friend_request,      // Add friend request    cmd_add_friend_response,     // Add friend response    cmd_friend_list,             // Get friend list    cmd_friend_chat,             // Friend chat    cmd_group_create,            // Create group    cmd_group_search,            // Search group    cmd_group_join_request,      // Join group request    cmd_group_join_response,     // Join group response    cmd_group_list,              // Get group list    cmd_group_chat,              // Group chat    cmd_group_member_list,       // Get group member list    cmd_group_member_add,        // Add group member    cmd_group_member_del,        // Delete group member    cmd_set_icon                 // Set avatar};

Command Processing Flowchart

C++ QT Project Recommendation - WeChat-like Chat Application with Linux C++ Backend

4.5 Core Command Details

User Authentication Commands

1. User Registration (cmd_regist = 0)

Client Request:

{    "cmd": 0,    "account": 12345,    "password": "123456",     "name": "Zhang San"}

Server Response:

{    "cmd": 0,    "res": "yes",  // or "no"    "err": "Account already exists"  // Error message on failure}

Processing Logic:

  • Check if the account already exists

  • Insert user record into the user table

  • Automatically add system friend (10000)

  • Return registration result

2. User Login (cmd_login = 1)

Client Request:

{    "cmd": 1,    "account": 12345,    "password": "123456"}

Server Response:

{    "cmd": 1,    "res": "yes",    "info": ["Zhang San", "hello", ":/Icons/src/QQIcon/icon.jpg"]}

Processing Logic:

  • Validate account password

  • Update online status to 1

  • Add connection to userMap

  • Return user basic information

Friend Management Commands

3. Search for Friends (cmd_friend_search = 3)

Client Request:

{    "cmd": 3,    "info": "12345"  // Account or nickname to search}

Server Response:

{    "cmd": 3,    "count": 1,    "msglist": [        {            "account": 12345,            "name": "Zhang San",            "signature": "hello",            "online": 1,            "icon": ":/Icons/src/QQIcon/icon.jpg"        }    ]}

4. Get Friend List (cmd_friend_list = 6)

Client Request:

{    "cmd": 6,    "account": 12345}

Server Response:

{    "cmd": 6,    "count": 2,    "msglist": [        {            "account": 10000,            "name": "System Message",            "signature": "Official system account",            "online": 1,            "icon": ":/Icons/src/QQIcon/icon.jpg"        },        {            "account": 54321,            "name": "Li Si",             "signature": "Online status",            "online": 0,            "icon": ":/Icons/src/QQIcon/icon.jpg"        }    ]}

5. Friend Chat (cmd_friend_chat = 7)

Client Request:

{    "cmd": 7,    "account": 12345,      // Sender account    "friendAccount": 54321, // Receiver account    "sendmsg": "Hello!"     // Message content}

Server Processing:

  • Forward the message to the online target friend

  • If the friend is offline, the message is not stored temporarily

Group Management Commands

6. Search for Groups (cmd_group_search = 9)

Client Request:

{    "cmd": 9,    "info": "Group name or group number"}

Server Response:

{    "cmd": 9,    "count": 1,    "msglist": [        {            "group_account": 100001,            "group_name": "Technical Exchange Group",            "group_master": 12345        }    ]}

7. Get Group List (cmd_group_list = 12)

Client Request:

{    "cmd": 12,    "account": 12345}

Server Response:

{    "cmd": 12,    "count": 1,    "msglist": [        {            "group_account": 100001,            "group_name": "Technical Exchange Group"        }    ]}

8. Group Chat (cmd_group_chat = 13)

Client Request:

{    "cmd": 13,    "account": 12345,    "groupAccount": 100001,    "sendmsg": "Hello everyone!"}

Server Processing:

  • Get all online group members

  • Broadcast the message to all online group members

  • Exclude the sender

4.6 GDB Network Debugging Details

Network Framework Debugging Flowchart

C++ QT Project Recommendation - WeChat-like Chat Application with Linux C++ Backend

Key Breakpoint Setting Strategy

Why set breakpoints at these locations?

C++ QT Project Recommendation - WeChat-like Chat Application with Linux C++ Backend

Detailed Debugging Steps

1. Main Function Debugging – Server Startup

Set Breakpoint:

(gdb) b mainNote: breakpoint 1 also set at pc 0x5555555782a2.Breakpoint 4 at 0x5555555782a2: file /home/lqf/linux/reactor/chat-forge/server/main.cpp, line 13.

Debugging Key Points:

  • Check database initialization:SQLite::Database db(“user.db”)

  • Validate table creation:CREATE TABLE IF NOT EXISTS user…

  • Confirm port settings:default_port = 8888

  • Observe socket creation:listen_fd = socket(AF_INET, SOCK_STREAM, 0)

Key Variable Monitoring:

(gdb) p default_port      # Monitor port number(gdb) p listen_fd         # Monitor socket file descriptor(gdb) info locals         # View all local variables

2. Accept Debugging – Connection Listening

Set Breakpoint:

(gdb) b accept# Or more precisely at the accept call in main.cpp(gdb) b main.cpp:88

Call Stack Analysis:

#0  __libc_accept (fd=4, addr=..., len=0x7fffffffde78) at ../sysdeps/unix/sysv/linux/accept.c:24#1  0x00005555555784f1 in main (argc=1, argv=0x7fffffffdfe8) at /home/lqf/linux/reactor/chat-forge/server/main.cpp:88

Debugging Key Points:

  • The server enters listening state, waiting for client connections

  • Observe client connection information: IP address and port

  • Monitor the socket file descriptor of the new connection

  • Validate thread creation and userMap updates

Key Variable Monitoring:

(gdb) p client_addr.sin_addr    # Client IP(gdb) p ntohs(client_addr.sin_port)  # Client port(gdb) p connect_fd              # New connection's socket fd(gdb) p userMap                 # Online user mapping table

3. Recv Debugging – Data Reception

Set Breakpoint:

(gdb) b Session::recvMsg# Or at the specific recv system call(gdb) b session.cpp:301

Call Stack Analysis:

#0  __libc_recv (fd=6, buf=0x7ffff71a0be4, len=4, flags=0) at ../sysdeps/unix/sysv/linux/recv.c:24#1   in Session::recvMsg[abi:cxx11]() (this=) at /home/lqf/linux/reactor/chat-forge/server/session.cpp:301#2   in taskThread (clientFd=6) at /home/lqf/linux/reactor/chat-forge/server/chatTask.cpp:13#3   in std::__invoke_impl<void, void (*)(int), int> (__f=@0x55555570cd80:  <taskThread(int)>) at /usr/include/c++/10/bits/invoke.h:60#4   in std::__invoke<void (*)(int), int> (__fn=@0x55555570cd80: 0x55555557455f <taskThread(int)>) at /usr/include/c++/10/bits/invoke.h:95#5   in std::thread::_Invoker<std::tuple<void (*)(int), int> >::_M_invoke<0ul, 1ul> (this=) at /usr/include/c++/10/thread:264#6   in std::thread::_Invoker<std::tuple<void (*)(int), int> >::operator() (this=) at /usr/include/c++/10/thread:271#7   in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(int), int> > >::_M_run (this=) at /usr/include/c++/10/thread:215#8   in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6#9   in start_thread (arg=<optimized out>) at pthread_create.c:477#10  in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Debugging Key Points:

  • First receive the 4-byte length header:recv(m_socket, buffer, 4, 0)

  • Then receive the complete JSON data:recv(m_socket, msg, len, MSG_WAITALL)

  • Validate protocol format: length prefix + JSON message body

  • Observe the JSON parsing process:json::parse(msg)

Key Variable Monitoring:

(gdb) p len                    # Message length(gdb) x/4xb buffer            # View the 4-byte length header in hexadecimal(gdb) p msg                   # JSON string content(gdb) p j                     # Parsed JSON object(gdb) p j["cmd"]              # Command type

Protocol Validation:

# View raw byte data(gdb) x/16xb buffer           # Hexadecimal view(gdb) printf "%s\n", msg      # Print JSON string

4. Send Debugging – Response Sending

Set Breakpoint:

(gdb) b Session::sendMsg# Or at the specific send system call(gdb) b session.cpp:244

Call Stack Analysis:

#0  __libc_send (fd=6, buf=0x7fffe8001180, len=78, flags=0) at ../sysdeps/unix/sysv/linux/send.c:24#1  0x000055555557c66a in Session::sendMsg (this=, j=...) at /home/lqf/linux/reactor/chat-forge/server/session.cpp:244#2  0x0000555555562e49 in CommandHandler::Login (account=110, password="1234", session=) at /home/lqf/linux/reactor/chat-forge/server/CommandHandler.cpp:65#3  0x000055555557b088 in Session::handleMsg (this=, msg=...) at /home/lqf/linux/reactor/chat-forge/server/session.cpp:58#4  0x000055555557ccb9 in Session::recvMsg[abi:cxx11]() (this=) at /home/lqf/linux/reactor/chat-forge/server/session.cpp:334#5  0x00005555555745d6 in taskThread (clientFd=6) at /home/lqf/linux/reactor/chat-forge/server/chatTask.cpp:13

Debugging Key Points:

  • Construct response JSON:j.dump()

  • Send length header:send(m_socket, message, 4, 0)

  • Send JSON data:send(m_socket, message+4, len, 0)

  • Validate sending status and data integrity

Key Variable Monitoring:

(gdb) p j                     # Response JSON object(gdb) p msg                   # JSON string(gdb) p len                   # Message length(gdb) x/4xb buffer           # Length header in hexadecimal(gdb) printf "%s\n", msg.c_str()  # Response content

Complete Debugging Session Example

# Start GDB debugging$ gdb ./server(gdb) b main(gdb) b accept  (gdb) b Session::recvMsg(gdb) b Session::sendMsg(gdb) run
# When the client connectsBreakpoint 2, accept (...)(gdb) p client_addr.sin_addr(gdb) c
# When the client sends a messageBreakpoint 3, Session::recvMsg (...)(gdb) p len(gdb) p msg(gdb) p j["cmd"](gdb) c
# When the server sends a responseBreakpoint 4, Session::sendMsg (...)(gdb) p j(gdb) printf "%s\n", msg.c_str()(gdb) c

Debugging Best Practices

Common Issue Troubleshooting

1. Connection Failure

  • Check if the port is occupied:netstat -tlnp | grep 8888

  • Validate firewall settings:iptables -L

  • Confirm server listening status:ss -tlnp | grep 8888

2. Message Parsing Error

  • Validate JSON format: use online JSON validation tools

  • Check character encoding: ensure UTF-8 encoding

  • Monitor message length: does the length header match the actual data?

3. Database Operation Failure

  • Check database file permissions:ls -la user.db

  • Validate SQL statements: test using sqlite3 command line tool

  • Monitor database locks: check for concurrent access conflicts

Performance Tuning Breakpoints

# Monitor thread creation(gdb) b pthread_create# Monitor database operations(gdb) b SQLite::Statement::executeStep# Monitor memory allocation(gdb) b malloc(gdb) b free

4.7 Performance Features and Limitations

Advantages

  • Simple and Intuitive: Clear architecture, easy to understand and maintain

  • Rapid Development: Based on mature SQLite and nlohmann/json libraries

  • Cross-Platform: Linux server + Windows/Linux client

Current Limitations

  • Concurrency Performance: One connection one thread model, high overhead in threads during high concurrency

  • Message Persistence: Offline messages are not stored, messages are lost when users are offline

  • Load Balancing: Single machine deployment, no cluster support

  • Security: Plaintext transmission, lacking encryption and authentication mechanisms

Optimization Suggestions

  • Introduce Thread Pool: Reduce thread creation and destruction overhead

  • Message Queue: Support offline message storage and push

  • Connection Pool: Optimize database connection management

  • SSL/TLS: Encrypt network transmission

  • Redis Cache: Improve online status query performance

5 Project Summary

5.1 Technology Stack Overview

C++ QT Project Recommendation - WeChat-like Chat Application with Linux C++ Backend

5.2 Architectural Advantages

  • High Development Efficiency: Based on mature open-source libraries, rapid prototype development

  • Simple Deployment: Single machine deployment, no complex dependencies

  • Easy to Debug: Clear architecture, clear debugging breakpoints

  • Cross-Platform: Client supports Windows/Linux

5.3 Applicable Scenarios

  • Learning Project: Understand network programming and database operations

  • Small Teams: Internal communication tool (<100 people)

  • Prototype Validation: Rapidly validate chat functionality requirements

  • Technical Demonstration: Showcase Qt + C++ technology stack

5.4 Expansion Directions

Function Expansion:

  • File transfer, image sharing

  • Voice/video calls

  • Message encryption, digital signatures

  • Offline messages, message history

Architecture Upgrade

  • Microservices, load balancing

  • Message queue, caching layer

  • Containerized deployment

  • Monitoring and alerting system

This project provides a complete foundational framework for an instant messaging system, suitable as a starting point for learning and further development.

Leave a Comment