以下是一个基于 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 消息。