hiredis 是一个轻量级的 C 语言 Redis 客户端库,提供了简单、高效的接口。它是 Redis 官方推荐的 C 客户端之一,专注于高性能和简洁的 API 设计。
sudo apt-get install libhiredis-dev
brew install hiredis
git clone https://github.com/redis/hiredis.git
cd hiredis
make
sudo make install
#include <hiredis/hiredis.h>
#include <hiredis/hiredis.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
// 连接到 Redis(默认地址 127.0.0.1:6379)
redisContext *c = redisConnect("127.0.0.1", 6379);
if (c == NULL || c->err) {
if (c) {
printf("Connection error: %s\n", c->errstr);
redisFree(c);
} else {
printf("Connection error: can't allocate redis context\n");
}
return 1;
}
printf("Connected to Redis\n");
// 断开连接
redisFree(c);
return 0;
}
#include <hiredis/hiredis.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
redisContext *c = redisConnect("127.0.0.1", 6379);
if (c == NULL || c->err) {
printf("Connection error: %s\n", c->errstr);
return 1;
}
// SET key value
redisReply *reply = (redisReply *)redisCommand(c, "SET %s %s", "name", "hiredis");
printf("SET: %s\n", reply->str);
freeReplyObject(reply);
// GET key
reply = (redisReply *)redisCommand(c, "GET %s", "name");
printf("GET name: %s\n", reply->str);
freeReplyObject(reply);
redisFree(c);
return 0;
}
#include <hiredis/hiredis.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
redisContext *c = redisConnect("127.0.0.1", 6379);
if (c == NULL || c->err) return 1;
// 字符串操作
redisReply *reply = (redisReply *)redisCommand(c, "SET %s %s", "counter", "100");
freeReplyObject(reply);
reply = (redisReply *)redisCommand(c, "INCR %s", "counter");
printf("INCR counter: %lld\n", reply->integer);
freeReplyObject(reply);
// 列表操作 LPUSH
reply = (redisReply *)redisCommand(c, "LPUSH mylist item1 item2 item3");
printf("LPUSH: %lld\n", reply->integer);
freeReplyObject(reply);
// 列表操作 LRANGE
reply = (redisReply *)redisCommand(c, "LRANGE mylist 0 -1");
printf("LRANGE mylist:\n");
for (size_t i = 0; i < reply->elements; i++) {
printf(" [%zu]: %s\n", i, reply->element[i]->str);
}
freeReplyObject(reply);
redisFree(c);
return 0;
}
#include <hiredis/hiredis.h>
#include <stdio.h>
int main() {
// 带密码连接
redisContext *c = redisConnectWithTimeout(
"127.0.0.1",
6379,
(struct timeval){.tv_sec = 2, .tv_usec = 0}
);
if (c == NULL || c->err) {
printf("Connection error: %s\n", c->errstr);
return 1;
}
// 认证
redisReply *reply = (redisReply *)redisCommand(c, "AUTH %s", "your_password");
if (reply->type == REDIS_REPLY_ERROR) {
printf("AUTH failed: %s\n", reply->str);
} else {
printf("AUTH success\n");
}
freeReplyObject(reply);
redisFree(c);
return 0;
}
#include <hiredis/hiredis.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
redisContext *c = redisConnect("127.0.0.1", 6379);
if (c == NULL || c->err) return 1;
// 发送多个命令但不读取回复
redisAppendCommand(c, "SET key1 value1");
redisAppendCommand(c, "SET key2 value2");
redisAppendCommand(c, "SET key3 value3");
redisAppendCommand(c, "GET key1");
redisAppendCommand(c, "GET key2");
// 读取所有回复
redisReply *reply;
for (int i = 0; i < 5; i++) {
redisGetReply(c, (void **)&reply);
printf("Reply %d: ", i + 1);
if (reply->type == REDIS_REPLY_STRING) {
printf("%s\n", reply->str);
} else if (reply->type == REDIS_REPLY_STATUS) {
printf("%s\n", reply->str);
} else {
printf("(type: %d)\n", reply->type);
}
freeReplyObject(reply);
}
redisFree(c);
return 0;
}
#include <hiredis/async.h>
#include <hiredis/adapters/libevent.h>
#include <event2/event.h>
#include <stdio.h>
#include <stdlib.h>
void connectCallback(const redisAsyncContext *c, int status) {
if (status != REDIS_OK) {
printf("Connect error: %s\n", c->errstr);
return;
}
printf("Connected to Redis (async)\n");
}
void disconnectCallback(const redisAsyncContext *c, int status) {
if (status != REDIS_OK) {
printf("Disconnect error: %s\n", c->errstr);
return;
}
printf("Disconnected\n");
}
void getCallback(redisAsyncContext *c, void *r, void *privdata) {
redisReply *reply = (redisReply *)r;
if (reply == NULL) return;
printf("GET result: %s\n", reply->str);
}
int main() {
struct event_base *base = event_base_new();
redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
if (c->err) {
printf("Connection error: %s\n", c->errstr);
return 1;
}
redisLibeventAttach(c, base);
redisAsyncSetConnectCallback(c, connectCallback);
redisAsyncSetDisconnectCallback(c, disconnectCallback);
// 异步命令
redisAsyncCommand(c, NULL, NULL, "SET %s %s", "async_key", "async_value");
redisAsyncCommand(c, getCallback, NULL, "GET %s", "async_key");
event_base_dispatch(base);
event_base_free(base);
return 0;
}
#include <hiredis/hiredis.h>
#include <stdio.h>
#include <stdlib.h>
void printReply(redisReply *reply) {
switch (reply->type) {
case REDIS_REPLY_STRING:
printf("STRING: %s\n", reply->str);
break;
case REDIS_REPLY_ARRAY:
printf("ARRAY (%zu elements):\n", reply->elements);
for (size_t i = 0; i < reply->elements; i++) {
printf(" [%zu] ", i);
printReply(reply->element[i]);
}
break;
case REDIS_REPLY_INTEGER:
printf("INTEGER: %lld\n", reply->integer);
break;
case REDIS_REPLY_NIL:
printf("NIL\n");
break;
case REDIS_REPLY_STATUS:
printf("STATUS: %s\n", reply->str);
break;
case REDIS_REPLY_ERROR:
printf("ERROR: %s\n", reply->str);
break;
default:
printf("UNKNOWN type: %d\n", reply->type);
}
}
int main() {
redisContext *c = redisConnect("127.0.0.1", 6379);
if (c == NULL || c->err) return 1;
// 设置一些数据
redisCommand(c, "SET key1 value1");
redisCommand(c, "LPUSH list1 a b c d e");
// 测试不同类型的回复
redisReply *reply;
// STRING
reply = (redisReply *)redisCommand(c, "GET key1");
printf("GET key1: ");
printReply(reply);
freeReplyObject(reply);
// INTEGER
reply = (redisReply *)redisCommand(c, "LLEN list1");
printf("LLEN list1: ");
printReply(reply);
freeReplyObject(reply);
// ARRAY
reply = (redisReply *)redisCommand(c, "LRANGE list1 0 -1");
printf("LRANGE list1: ");
printReply(reply);
freeReplyObject(reply);
// NIL
reply = (redisReply *)redisCommand(c, "GET nonexistent");
printf("GET nonexistent: ");
printReply(reply);
freeReplyObject(reply);
redisFree(c);
return 0;
}
#include <hiredis/hiredis.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
class RedisCache {
private:
redisContext *context_;
public:
RedisCache(const char *host = "127.0.0.1", int port = 6379) {
context_ = redisConnect(host, port);
if (context_ == NULL || context_->err) {
printf("Redis connection failed\n");
context_ = NULL;
}
}
~RedisCache() {
if (context_) {
redisFree(context_);
}
}
bool isConnected() const {
return context_ != NULL;
}
bool set(const char *key, const char *value, int seconds = 0) {
redisReply *reply;
if (seconds > 0) {
reply = (redisReply *)redisCommand(context_, "SETEX %s %d %s", key, seconds, value);
} else {
reply = (redisReply *)redisCommand(context_, "SET %s %s", key, value);
}
bool success = (reply->type == REDIS_REPLY_STATUS);
freeReplyObject(reply);
return success;
}
bool get(const char *key, char *buffer, size_t buffer_size) {
redisReply *reply = (redisReply *)redisCommand(context_, "GET %s", key);
bool success = false;
if (reply->type == REDIS_REPLY_STRING && reply->len < buffer_size) {
strncpy(buffer, reply->str, buffer_size);
success = true;
}
freeReplyObject(reply);
return success;
}
bool del(const char *key) {
redisReply *reply = (redisReply *)redisCommand(context_, "DEL %s", key);
bool success = (reply->integer > 0);
freeReplyObject(reply);
return success;
}
};
int main() {
RedisCache cache;
if (!cache.isConnected()) {
printf("Failed to connect to Redis\n");
return 1;
}
// 设置缓存(10秒过期)
cache.set("user:1001", "{\"name\":\"Alice\",\"age\":25}", 10);
// 获取缓存
char value[256];
if (cache.get("user:1001", value, sizeof(value))) {
printf("Cached data: %s\n", value);
}
return 0;
}
| 类型常量 | 数值 | 说明 |
|---|---|---|
REDIS_REPLY_STRING |
1 | 字符串 |
REDIS_REPLY_ARRAY |
2 | 数组 |
REDIS_REPLY_INTEGER |
3 | 整数 |
REDIS_REPLY_NIL |
4 | 空值 |
REDIS_REPLY_STATUS |
5 | 状态 |
REDIS_REPLY_ERROR |
6 | 错误 |