果然,高端的程序員真心是鳥都不鳥windows的,redis的客戶端找了一圈愣是沒有C++的windows版本
我要做個windows上的C++的服務器都沒辦法和redis交互
github上所有能試的我都試過了,要么是只支持unix,要么是怎么編譯都不通過,焦頭爛額中
然后我總結了網上無數的教程,附帶修復一個個編譯錯誤,總結如下
編譯環境,32位windows7,VS2013
獲取redis windows版
編譯 redis:
1.解壓到redis(文件夾名字自定義),打開msvs用vs 打開RedisServer.sln項目,編譯全部。
2.編譯完成后在DUBUG里面找5個EXE文件,分別是redis-benchmark.exe,redis-check-aof.exe,redis-check-dump.exe,redis-cli.exe,redis-server.exe
把5個EXE復制到redis的根目錄下即可(與bin文件夾同目錄),它們的作用如下:
redis-server:Redis服務器的daemon啟動程序
redis-cli:Redis命令行操作工具。也可以用telnet根據其純文本協議來操作
redis-benchmark:Redis性能測試工具,測試Redis在當前系統下的讀寫性能
redis-check-aof:數據修復
redis-check-dump:檢查導出工具
3.修改redis配置文件,根目錄下的redis.conf文件
參數介紹:
daemonize:是否以后台daemon方式運行
pidfile:pid文件位置
port:監聽的端口號
timeout:請求超時時間
loglevel:log信息級別
logfile:log文件位置
databases:開啟數據庫的數量
save * *:保存快照的頻率,第一個*表示多長時間,第三個*表示執行多少次寫操作。在一定時間內執行一定數量的寫操作時,自動保存快照。可設置多個條件。
rdbcompression:是否使用壓縮
dbfilename:數據快照文件名(只是文件名,不包括目錄)
dir:數據快照的保存目錄(這個是目錄)
appendonly:是否開啟appendonlylog,開啟的話每次寫操作會記一條log,這會提高數據抗風險能力,但影響效率。
appendfsync:appendonlylog如何同步到磁盤(三個選項,分別是每次寫都強制調用fsync、每秒啟用一次fsync、不調用fsync等待系統自己同步)
4.啟動redis
進入redis目錄后 開啟服務 (注意加上redis.conf)
redis-server.exe redis.conf
這個窗口要保持開啟 關閉時redis服務會自動關閉redis會自動保存數據到硬盤
5.測試使用
另外開啟一個命令行窗口 進入redis目錄下 (注意修改自己的ip)
1.redis-cli.exe -h 192.168.10.61 -p 6379
編譯 hiredis(其實上面編譯全部reids的時候已經編譯過的):
1.編譯兩個lib: hiredis.lib和Win32_Interop.lib
打開從GitHub上clone下來的文件夾,打開里面的msvs文件夾中的RedisServer.sln
從解決方案資源管理器窗口編譯hiredis工程和Win32_Interop工程(調試的時候請在debug模式下編譯這兩個庫),此時便會在Debug/Release文件夾下生成這兩個工程編譯的lib
2.在自己的工程中使用
(1)添加上一步編譯的這兩個lib到工程中
(2)復制GItHub redis項目文件夾中src/Win32_Interop下所有頭文件
(3)以及deps/hiredis下所有頭文件(其中fmacros.h用src文件夾下的fmacros.h文件替代)
(4)再復制src/Win32_Interop/win32fixes.c到自己的工程目錄,包含到工程文件中
(5)調整各個文件include的路徑
(6)示例代碼
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <hiredis.h> #define NO_QFORKIMPL //這一行必須加才能正常使用 #include <Win32_Interop\win32fixes.h> #pragma comment(lib,"hiredis.lib") #pragma comment(lib,"Win32_Interop.lib") int main() { unsigned int j; redisContext *c; redisReply *reply; struct timeval timeout = { 1, 500000 }; // 1.5 seconds c = redisConnectWithTimeout((char*)"127.0.0.1", 6379, timeout); if (c->err) { printf("Connection error: %s\n", c->errstr); exit(1); } /* PING server */ reply = (redisReply *)redisCommand(c, "PING"); printf("PING: %s\n", reply->str); freeReplyObject(reply); /* Set a key */ reply = (redisReply *)redisCommand(c, "SET %s %s", "foo", "hello world"); printf("SET: %s\n", reply->str); freeReplyObject(reply); /* Set a key using binary safe API */ reply = (redisReply *)redisCommand(c, "SET %b %b", "bar", 3, "hello", 5); printf("SET (binary API): %s\n", reply->str); freeReplyObject(reply); /* Try a GET and two INCR */ reply = (redisReply *)redisCommand(c, "GET foo"); printf("GET foo: %s\n", reply->str); freeReplyObject(reply); reply = (redisReply *)redisCommand(c, "INCR counter"); printf("INCR counter: %lld\n", reply->integer); freeReplyObject(reply); /* again ... */ reply = (redisReply *)redisCommand(c, "INCR counter"); printf("INCR counter: %lld\n", reply->integer); freeReplyObject(reply); /* Create a list of numbers, from 0 to 9 */ reply = (redisReply *)redisCommand(c, "DEL mylist"); freeReplyObject(reply); for (j = 0; j < 10; j++) { char buf[64]; sprintf_s(buf, 64, "%d", j); reply = (redisReply *)redisCommand(c, "LPUSH mylist element-%s", buf); freeReplyObject(reply); } /* Let's check what we have inside the list */ reply = (redisReply *)redisCommand(c, "LRANGE mylist 0 -1"); if (reply->type == REDIS_REPLY_ARRAY) { for (j = 0; j < reply->elements; j++) { printf("%u) %s\n", j, reply->element[j]->str); getchar(); } } freeReplyObject(reply); return 0; }
PS.可能會碰到的編譯錯誤
1.必須定義入口點,請在win32fixes.h之前加上#define NO_QFORKIMPL
2.各種與其他庫的使用沖突,請右擊項目->屬性->配置屬性->C/C++->代碼生成->運行庫->改成多線程調試(/MTd)或多線程(/MT)
並且在右擊項目->屬性->配置屬性->連接器->命令行中輸入/NODEFAULTLIB:libcmt.lib
3.error C4996,各種unsafe報錯啊,請右擊項目->屬性->配置屬性->C/C++->預處理器->預處理器定義->添加“_CRT_SECURE_NO_WARNINGS”(不帶引號)