以下是一個基于 Linux 的 C 程序示例,展示了如何使用 Unix 域套接字(Unix domain socket)在不同進程之間互傳 JSON 消息。我們將實現一個簡單的客戶端 - 服務器模型,服務器監聽連接,客戶端連接到服務器并發送 JSON 消息,服務器接收消息并打印出來,然后服務器也可以向客戶端發送 JSON 消息。
服務器端代碼(server.c)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <json-c/json.h>#define SOCKET_PATH "/tmp/my_socket"int main() {int server_fd, new_socket;struct sockaddr_un address;int opt = 1;int addrlen = sizeof(address);char buffer[1024] = {0};// 創建套接字if ((server_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == 0) {perror("socket failed");exit(EXIT_FAILURE);}// 設置套接字選項if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {perror("setsockopt");exit(EXIT_FAILURE);}address.sun_family = AF_UNIX;strcpy(address.sun_path, SOCKET_PATH);// 綁定套接字到指定路徑if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {perror("bind failed");exit(EXIT_FAILURE);}// 監聽連接if (listen(server_fd, 3) < 0) {perror("listen");exit(EXIT_FAILURE);}printf("Server listening on %s...\n", SOCKET_PATH);// 接受客戶端連接if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {perror("accept");exit(EXIT_FAILURE);}// 接收客戶端發送的 JSON 消息ssize_t valread = read(new_socket, buffer, 1024);if (valread < 0) {perror("read");exit(EXIT_FAILURE);}// 解析 JSON 消息json_object *parsed_json = json_tokener_parse(buffer);if (parsed_json == NULL) {printf("Failed to parse JSON\n");} else {printf("Received JSON: %s\n", json_object_to_json_string(parsed_json));json_object_put(parsed_json);}// 向客戶端發送 JSON 消息json_object *response_json = json_object_new_object();json_object_object_add(response_json, "message", json_object_new_string("Hello from server!"));const char *response_str = json_object_to_json_string(response_json);send(new_socket, response_str, strlen(response_str), 0);json_object_put(response_json);// 關閉套接字close(new_socket);close(server_fd);unlink(SOCKET_PATH);return 0;
}
客戶端代碼(client.c)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <json-c/json.h>#define SOCKET_PATH "/tmp/my_socket"int main() {int sock = 0;struct sockaddr_un serv_addr;char buffer[1024] = {0};// 創建套接字if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {perror("socket creation error");return -1;}serv_addr.sun_family = AF_UNIX;strcpy(serv_addr.sun_path, SOCKET_PATH);// 連接到服務器if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {perror("Connection Failed");return -1;}// 創建 JSON 消息json_object *json_msg = json_object_new_object();json_object_object_add(json_msg, "message", json_object_new_string("Hello from client!"));const char *msg_str = json_object_to_json_string(json_msg);// 發送 JSON 消息send(sock, msg_str, strlen(msg_str), 0);json_object_put(json_msg);// 接收服務器的響應ssize_t valread = read(sock, buffer, 1024);if (valread < 0) {perror("read");return -1;}// 解析服務器的響應json_object *parsed_json = json_tokener_parse(buffer);if (parsed_json == NULL) {printf("Failed to parse JSON\n");} else {printf("Received JSON from server: %s\n", json_object_to_json_string(parsed_json));json_object_put(parsed_json);}// 關閉套接字close(sock);return 0;
}
編譯和運行
1. 安裝 json-c 庫:
sh
sudo apt-get install
?libjson-c-dev
2. 編譯服務器端和客戶端代碼:
sh
gcc server.c -o
?server -ljson-c
gcc client.c?
-o
?client -ljson-c
3. 先運行服務器:
sh
./server
4. 再運行客戶端:
sh
./client
代碼說明
? 服務器端:創建一個 Unix 域套接字,綁定到指定路徑,監聽連接,接受客戶端連接,接收客戶端發送的 JSON 消息,解析并打印該消息,然后向客戶端發送一條 JSON 響應消息。
? 客戶端:創建一個 Unix 域套接字,連接到服務器,創建一個 JSON 消息并發送給服務器,接收服務器的響應消息,解析并打印該消息。
通過這種方式,不同進程之間可以使用 Unix 域套接字互傳 JSON 消息。