一个 C 语言编写的客户端程序,用于通过 HTTP 协议与指定服务器上的 API 进行通信,具体来说是发送请求到一个类似 Ollama 的大语言模型 API 并接收响应。
简单来说,这个程序的作用是:运行时接收一个提示词作为参数,然后向指定 IP 和端口的大语言模型 API 发送请求,获取模型的生成结果并打印出来。这类似于通过命令行调用 AI 模型进行问答。这段代码是一个 C 语言编写的客户端程序,用于通过 HTTP 协议与指定服务器上的 API 进行通信,具体来说是发送请求到一个类似 Ollama 的大语言模型 API 并接收响应。
·
#include <stdio.h> // 引入标准输入输出库,用于printf等函数
#include <stdlib.h> // 引入标准库,用于内存分配、程序退出等功能
#include <string.h> // 引入字符串处理库,用于字符串操作函数
#include <unistd.h> // 引入Unix标准库,提供read、write、close等系统调用
#include <arpa/inet.h> // 引入网络地址转换库,提供IP地址转换等功能
#define PORT 11434 // 定义服务器端口号(Ollama默认端口)
#define SERVER_IP "172.20.10.6" // 定义目标服务器的IP地址
#define BUFFER_SIZE 4096 * 10 // 定义接收缓冲区大小为40KB
int main(int argc, char const *argv[]) // 主函数,argc为参数数量,argv为参数数组
{
if (argc != 2) // 检查命令行参数是否为2个(程序名+提示词)
{
printf("Usage: %s <prompt>\n", argv[0]); // 打印程序正确使用方法
return 1; // 参数错误,返回1退出程序
}
int sock = 0; // 声明socket文件描述符并初始化
struct sockaddr_in serv_addr; // 声明服务器地址结构体
char buffer[BUFFER_SIZE] = {0}; // 声明接收缓冲区并初始化为0
// 创建TCP socket:AF_INET(IPv4),SOCK_STREAM(TCP),0(默认协议)
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Socket creation error \n"); // 打印socket创建失败信息
return -1; // 创建失败,返回-1退出
}
serv_addr.sin_family = AF_INET; // 设置地址族为IPv4
serv_addr.sin_port = htons(PORT); // 将端口号转换为网络字节序(大端模式)
// 将字符串形式的IP地址转换为二进制格式,存储到服务器地址结构体
if (inet_pton(AF_INET, SERVER_IP, &serv_addr.sin_addr) <= 0)
{
printf("\nInvalid address/ Address not supported \n"); // 打印地址无效信息
return -1; // 地址错误,返回-1退出
}
// 连接到服务器,参数为socket描述符、服务器地址结构体、结构体大小
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nConnection Failed \n"); // 打印连接失败信息
return -1; // 连接失败,返回-1退出
}
// 声明并初始化HTTP请求体缓冲区
char request_body[1024] = {0};
// 格式化构造JSON请求体,包含模型名称、提示词和其他参数
snprintf(request_body, 1024, "{\"model\": \"deepseek-r1:1.5b\", \"prompt\": \"%s\", \"stream\": false,\"include_context\": false}", argv[1]);
// 声明HTTP请求头缓冲区
char request_headers[256] = {0};
// 格式化构造HTTP请求头,包含请求方法、路径、主机、内容类型和长度
snprintf(request_headers, sizeof(request_headers),
"POST /api/generate HTTP/1.1\r\n"
"Host: 192.168.128.196:11434\r\n"
"Content-Type: application/json\r\n"
"Content-Length: %zu\r\n"
"\r\n",
strlen(request_body));
// 声明完整HTTP请求缓冲区
char request[4096] = {0};
// 将请求头和请求体组合成完整的HTTP请求
snprintf(request, sizeof(request), "%s%s", request_headers, request_body);
// 发送HTTP请求到服务器
send(sock, request, strlen(request), 0);
printf("Request sent:\n%s\n", request); // 打印已发送的请求内容
while (1) // 无限循环接收服务器响应
{
// 从socket读取响应数据到缓冲区
int valread = read(sock, buffer, BUFFER_SIZE);
if (valread > 0) // 成功读取到数据
{
printf("Response:\n%s\n", buffer); // 打印接收到的响应内容
}
else // 读取失败或连接关闭
{
printf("Failed to receive response.\n"); // 打印接收失败信息
}
}
// 关闭socket连接(注:由于上面是无限循环,此行实际不会执行)
close(sock);
return 0; // 程序正常退出
}
这段代码是一个 C 语言编写的客户端程序,用于通过 HTTP 协议与指定服务器上的 API 进行通信,具体来说是发送请求到一个类似 Ollama 的大语言模型 API 并接收响应。
让我为你详细解释代码的各个部分:
-
头文件和宏定义:
- 包含了网络编程、输入输出、字符串处理等必要的头文件
- 定义了端口号
PORT为 11434(这是 Ollama 默认使用的端口) - 定义了服务器 IP 地址
SERVER_IP - 定义了缓冲区大小
BUFFER_SIZE
-
参数检查:
- 检查程序运行时是否提供了一个命令行参数(prompt 内容)
- 如果参数数量不对,打印使用方法并退出
-
Socket 创建与初始化:
- 创建一个 TCP socket(
SOCK_STREAM) - 设置服务器地址结构,包括地址族、端口号
- 将服务器 IP 地址从字符串转换为二进制格式
- 创建一个 TCP socket(
-
连接服务器:
- 使用
connect函数尝试连接到指定的服务器和端口 - 如果连接失败,打印错误信息并退出
- 使用
-
构造 HTTP 请求:
- 构造请求体(JSON 格式),包含模型名称(
deepseek-r1:1.5b)、提示词(从命令行参数获取)和其他参数 - 构造 HTTP 请求头,包含请求方法(POST)、目标路径(
/api/generate)、主机地址、内容类型和内容长度 - 将请求头和请求体组合成完整的 HTTP 请求
- 构造请求体(JSON 格式),包含模型名称(
-
发送请求与接收响应:
- 使用
send函数发送 HTTP 请求到服务器 - 进入循环,使用
read函数持续接收服务器的响应数据 - 每次接收到数据后,将其打印出来
- 注意:这段代码的循环没有退出条件,会一直运行直到程序被强制终止
- 使用
-
关闭连接:
- 关闭 socket 连接(虽然在当前代码中因为循环没有退出条件,这行代码实际上永远不会被执行)
简单来说,这个程序的作用是:运行时接收一个提示词作为参数,然后向指定 IP 和端口的大语言模型 API 发送请求,获取模型的生成结果并打印出来。这类似于通过命令行调用 AI 模型进行问答。
编辑分享
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)