基于C语言实现MQTT over WebSocket入门指引请求(不使用现成库)
Hey there! Since you already have a solid grasp on MQTT over TCP with Mosquitto, you’re already halfway there—great foundation to build on. Let’s break down your questions and walk through a practical starting point for raw socket-based WebSocket + MQTT implementation.
Core Questions Answered
1. Can WebSocket be implemented using raw TCP sockets?
Absolutely! WebSocket is built on top of TCP—it’s just a higher-level protocol that adds a handshake mechanism and a frame structure to standard TCP. You can absolutely use raw TCP sockets to implement WebSocket; you just need to handle two key parts:
- The initial HTTP-based upgrade handshake to switch the TCP connection from HTTP to WebSocket.
- Encoding/decoding WebSocket frames for all subsequent data transfer.
2. Is HTTP mandatory for MQTT over WebSocket?
Yes, it is—at least for the initial connection setup. The WebSocket protocol requires an HTTP Upgrade handshake to establish the connection. Here’s why:
- Clients start by sending an HTTP GET request with specific headers (
Upgrade: websocket,Connection: Upgrade,Sec-WebSocket-Key, etc.). - The server responds with a
101 Switching Protocolsstatus, confirming the upgrade to WebSocket.
Once this handshake is done, you no longer use HTTP—all subsequent traffic is WebSocket frames containing your MQTT payloads.
Step-by-Step Raw Socket Implementation Guide
Since you want to avoid libraries like Paho and have limited socket experience, let’s take this slow, focusing on the critical parts:
1. First: Master the WebSocket Basics
Start by learning two key components of WebSocket (skip the rest of the RFC unless you need it):
- Handshake Flow: Study the request/response headers required to upgrade the connection. The most critical part is calculating the
Sec-WebSocket-Acceptvalue from the client’sSec-WebSocket-Key(append the fixed string258EAFA5-E914-47DA-95CA-C5AB0DC85B11, compute SHA-1 hash, then Base64 encode the result). - Frame Format: Understand how WebSocket wraps data. Key fields:
FIN: Indicates if this is the final frame in a message.Opcode: Use0x02for binary frames (perfect for MQTT’s binary payloads).Mask: Client-to-server frames must include a 4-byte mask; server-to-client frames don’t.Payload Length: Can be 1 byte, 2 bytes, or 8 bytes depending on data size.Payload Data: Your actual MQTT frame (after applying/unapplying the mask if needed).
2. Build a Minimal WebSocket Handshake Handler
Start with a simple TCP socket server/client and implement the handshake first:
- Server Side:
- Create a TCP socket, bind to a port, and listen for connections.
- When a client connects, read the HTTP request headers.
- Extract
Sec-WebSocket-Keyfrom the headers. - Compute the
Sec-WebSocket-Acceptvalue as described. - Send back a 101 response with the
Sec-WebSocket-Acceptheader.
- Client Side:
- Create a TCP socket and connect to the server.
- Send the HTTP GET request with all required WebSocket headers.
- Read the server’s 101 response to confirm the upgrade.
Test this handshake first—make sure the connection stays open after the handshake (don’t close the socket!).
3. Add WebSocket Frame Encoding/Decoding
Once the handshake works, implement functions to:
- Encode MQTT frames into WebSocket frames:
- Take your existing MQTT binary frame (the same one you send over TCP).
- Wrap it in a WebSocket binary frame (set opcode to
0x02, FIN to1, no mask if you’re the server).
- Decode WebSocket frames to get MQTT frames:
- Read raw bytes from the TCP socket.
- Parse the WebSocket frame header to extract payload length and mask (if present).
- Apply the mask (if client-to-server) to get the raw MQTT frame.
- Pass this MQTT frame to your existing MQTT frame processing code (you already know how to handle this!).
4. Integrate MQTT Logic
Now that you can send/receive WebSocket frames, plug in your existing MQTT code:
- For a client: After the WebSocket handshake, send your MQTT
CONNECTframe wrapped in a WebSocket binary frame. Then handle incoming WebSocket frames, decode to get MQTT frames, and process them as you would over TCP. - For a server (if you’re extending Mosquitto or building your own): When a WebSocket connection is established, treat it like a regular MQTT TCP connection—just add the WebSocket frame wrapper/unwrapper step before processing MQTT data.
Pro Tips for Beginners
- Start small: Build a WebSocket echo server first (send back whatever data you receive) to test frame encoding/decoding without MQTT. Once that works, add MQTT.
- Use debug tools: Wireshark can help you inspect WebSocket handshakes and frames to verify your implementation matches the spec.
- Reuse your MQTT code: You don’t need to rewrite any MQTT logic—just add the WebSocket layer as a wrapper around your existing TCP-based MQTT handling.
内容的提问来源于stack exchange,提问作者user9703977

