``` #include <stdio.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <stdlib.h> #include <json/json.h> #include <pthread.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include "video.h" #include "motor.h" int main() { int sockfd = socket(AF_INET, SOCK_STREAM, 0); if (-1 == sockfd) { perror("socket"); exit(1); } struct sockaddr_in ali_addr; memset(&ali_addr, 0, sizeof(ali_addr)); ali_addr.sin_family = AF_INET; ali_addr.sin_port = htons(ALI_PORT); ali_addr.sin_addr.s_addr = inet_addr(ALI_ADDR); //connect ali server if (connect(sockfd, (struct sockaddr *)&ali_addr, sizeof(ali_addr)) < 0) { perror("connect ali server failure"); exit(1); } //create json object struct json_object *obj = (struct json_object *)json_object_new_object(); json_object_object_add(obj, "cmd", json_object_new_string("info")); json_object_object_add(obj, "deviceid", json_object_new_string("0001")); const char *s = (const char *)json_object_to_json_string(obj); if (send(sockfd, s, strlen(s), 0) < 0) { perror("send to ali failure"); exit(1); } //recv server port info char buf[256] = {0}; if (recv(sockfd, buf, sizeof(buf), 0) < 0) { perror("recv from server failure"); exit(1); } struct json_object *json = json_tokener_parse(buf); struct json_object *cmd, *port; int server_udp_port; cmd = json_object_object_get(json, "cmd"); port = json_object_object_get(json, "port"); if (!strcmp((const char *)json_object_get_string(cmd), "port_info")) { server_udp_port = json_object_get_int(port); } else { printf("recv from server error\n"); } //start new thread, send video data to ali server pthread_t tid; pthread_create(&tid, NULL, send_video_data, &server_udp_port); while (1) { memset(buf, 0, sizeof(buf)); if (recv(sockfd, buf, sizeof(buf), 0) < 0) { perror("recv failure"); } json = json_tokener_parse(buf); struct json_object *cmd, *action; cmd = json_object_object_get(json, "cmd"); action = json_object_object_get(json, "action"); if (!strcmp((const char *)json_object_get_string(cmd), "control")) { const char *act = json_object_get_string(action); if (!strcmp(act, "left")) //left { motor_turn_left(); } else if (!strcmp(act, "right")) { motor_turn_right(); } else if (!strcmp(act, "up")) { motor_turn_up(); } else if (!strcmp(act, "down")) { motor_turn_down(); } } } return 0; }```注释代码
时间: 2025-07-16 21:21:49 浏览: 5
<think>好的,我现在需要给用户提供的C语言代码添加注释。首先,我会通读整个代码,理解它的结构和功能。这段代码看起来是一个客户端程序,连接到阿里服务器,发送信息,接收端口信息,然后启动线程发送视频数据,并持续接收控制命令来控制电机。
接下来,我需要逐行分析代码,确定每个部分的作用。首先,main函数开始创建了一个socket文件描述符,使用AF_INET和SOCK_STREAM,这应该是TCP套接字。如果创建失败,会输出错误信息并退出。这里可能需要注释说明socket的创建及其参数。
然后是设置ali_addr结构体,这里使用了memset清零,设置地址族、端口和IP地址。ALI_PORT和ALI_ADDR可能是宏定义,需要指出。connect函数尝试连接到服务器,如果失败则报错。
接下来是创建JSON对象,添加"cmd"和"deviceid"字段,转换成字符串后通过send发送。这里可能需要解释json库的使用,比如使用的可能是libjson-c库。
接收服务器返回的端口信息,解析JSON得到UDP端口号,并启动线程send_video_data,传入端口号。这里需要说明新线程的作用是发送视频数据,可能通过UDP协议。
主循环中持续接收控制命令,解析JSON中的cmd和action,根据不同的动作调用相应的电机控制函数。这部分需要注释每个条件判断对应的动作。
在注释过程中,要确保技术术语正确,比如指出socket的类型、结构体的作用、JSON处理函数的功能,以及多线程的使用。同时,要注意代码中的错误处理,比如perror和exit的使用。
可能需要注意的地方:json_object_object_add和json_tokener_parse等函数属于哪个库,是否需要说明。另外,motor_turn_left等函数可能来自引入的头文件motor.h,视频相关函数来自video.h,这些头文件的作用也需要提及。
最后,总结整个代码的工作流程:连接到服务器,交换信息,启动视频传输线程,处理控制命令。确保注释覆盖主要步骤,帮助读者理解代码结构和功能。</think>以下是对该代码的逐段注释及功能说明:
$$
\text{代码功能概要}
\begin{cases}
1. 创建TCP客户端连接阿里云服务器 \\
2. 发送设备信息并接收视频传输端口 \\
3. 创建线程发送视频流数据 \\
4. 主循环接收控制指令操作电机
\end{cases}
$$
```c
#include <stdio.h> // 标准输入输出
#include <sys/types.h> // 系统数据类型定义
#include <sys/socket.h> // 套接字编程接口
#include <stdlib.h> // 标准库函数
#include <json/json.h> // JSON解析库(libjson-c)
#include <pthread.h> // POSIX线程库
#include <string.h> // 字符串处理
#include <netinet/in.h> // 网络地址结构体定义
#include <arpa/inet.h> // IP地址转换函数
#include "video.h" // 自定义视频处理头文件
#include "motor.h" // 自定义电机控制头文件
int main()
{
// 创建TCP套接字
// AF_INET=IPv4, SOCK_STREAM=TCP
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (-1 == sockfd) {
perror("socket");
exit(1);
}
// 配置服务器地址结构
struct sockaddr_in ali_addr;
memset(&ali_addr, 0, sizeof(ali_addr));
ali_addr.sin_family = AF_INET; // IPv4地址族
ali_addr.sin_port = htons(ALI_PORT); // 端口号(宏定义)
ali_addr.sin_addr.s_addr = inet_addr(ALI_ADDR); // IP地址(宏定义)
// 连接阿里云服务器
if (connect(sockfd, (struct sockaddr *)&ali_addr, sizeof(ali_addr)) < 0) {
perror("connect ali server failure");
exit(1);
}
/* 创建JSON对象并发送设备信息 */
struct json_object *obj = json_object_new_object(); // 创建根对象
// 添加字段:指令类型为设备信息
json_object_object_add(obj, "cmd", json_object_new_string("info"));
// 添加设备ID字段
json_object_object_add(obj, "deviceid", json_object_new_string("0001"));
const char *s = json_object_to_json_string(obj); // 序列化为JSON字符串
// 发送设备信息到服务器
if (send(sockfd, s, strlen(s), 0) < 0) {
perror("send to ali failure");
exit(1);
}
/* 接收服务器返回的UDP端口信息 */
char buf[256] = {0};
if (recv(sockfd, buf, sizeof(buf), 0) < 0) {
perror("recv from server failure");
exit(1);
}
// 解析JSON响应
struct json_object *json = json_tokener_parse(buf); // 解析JSON字符串
struct json_object *cmd, *port;
int server_udp_port;
// 获取字段值
cmd = json_object_object_get(json, "cmd");
port = json_object_object_get(json, "port");
// 验证指令类型并获取UDP端口号
if (!strcmp(json_object_get_string(cmd), "port_info")) {
server_udp_port = json_object_get_int(port);
} else {
printf("recv from server error\n");
}
/* 创建视频传输线程 */
pthread_t tid;
// 启动线程发送视频数据(使用UDP端口)
pthread_create(&tid, NULL, send_video_data, &server_udp_port);
/* 主循环接收控制指令 */
while (1) {
memset(buf, 0, sizeof(buf));
if (recv(sockfd, buf, sizeof(buf), 0) < 0) {
perror("recv failure");
}
// 解析控制指令
json = json_tokener_parse(buf);
struct json_object *cmd, *action;
cmd = json_object_object_get(json, "cmd");
action = json_object_object_get(json, "action");
// 执行对应电机动作
if (!strcmp(json_object_get_string(cmd), "control")) {
const char *act = json_object_get_string(action);
if (!strcmp(act, "left")) { // 左转
motor_turn_left();
} else if (!strcmp(act, "right")) { // 右转
motor_turn_right();
} else if (!strcmp(act, "up")) { // 上转
motor_turn_up();
} else if (!strcmp(act, "down")) { // 下转
motor_turn_down();
}
}
}
return 0;
}
```
$$
\text{代码执行流程图}
\begin{array}{|c|c|}
\hline
\text{阶段} & \text{操作} \\
\hline
初始化 & 创建TCP套接字 → 连接服务器 \\
\hline
注册设备 & 发送JSON设备信息 → 接收UDP端口 \\
\hline
视频传输 & 创建线程发送视频流数据 \\
\hline
控制循环 & 持续接收JSON指令 → 控制电机动作 \\
\hline
\end{array}
$$
主要特点:
1. 使用TCP进行控制信令传输,UDP进行视频流传输(通过`send_video_data`线程实现)
2. 采用JSON格式进行数据交换,提高可扩展性
3. 多线程设计分离视频传输和指令处理
4. 硬件控制通过`motor.h`接口实现平台无关性
阅读全文
相关推荐










