server.db = zmalloc(sizeof(redisDb)*server.dbnum);
//開闢緩衝區 redis
listenToPort(server.port,server.ipfd,&server.ipfd_count); dom
顯然這個函數是監聽端口 socket
跟蹤這個函數,進入,發現最終是掉用_anetTcpServer函數。 ide
下面是_anetTcpServer函數的解析。 函數
static int _anetTcpServer(char *err, int port, char *bindaddr, int af)
{
int s, rv;
char _port[6]; /* strlen("65535") */
//監聽端口
struct addrinfo hints;
//.ai_family = AF_INET;
//.ai_socktype = SOCK_STREAM;
//.ai_flags = AI_PASSIVE;
struct addrinfo *servinfo;
struct addrinfo *p;
oop
snprintf(_port,6,"%d",port);
memset(&hints,0,sizeof(hints));
hints.ai_family = af;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE; /* No effect if bindaddr != NULL */
優化
if ((rv = getaddrinfo(bindaddr,_port,&hints,&servinfo)) != 0) {
anetSetError(err, "%s", gai_strerror(rv));
return ANET_ERR;
//獲取解析的信息鏈表
}
for (p = servinfo; p != NULL; p = p->ai_next)
{
if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == -1)
continue;
//建立一個socket
this
if (af == AF_INET6 && anetV6Only(err,s) == ANET_ERR) goto error;
if (anetSetReuseAddr(err,s) == ANET_ERR) goto error;
//設置socket重用
if (anetListen(err,s,p->ai_addr,p->ai_addrlen) == ANET_ERR) goto error;
//bind & listen
goto end;
}
if (p == NULL) {
anetSetError(err, "unable to bind socket");
goto error;
} spa
error:
s = ANET_ERR;
end:
freeaddrinfo(servinfo);
return s;
}
總結:實現了socket,bind,listen並對socket設置了一些優化措施,好比設置passive,重用等。 .net
成功的socket存於server.ipfd,個數由server.ipfd_count指示。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
下面的代碼
/* Open the listening Unix domain socket. */用於創建unix 域socket
剛纔特地看了配置文件
# Specify the path for the unix socket that will be used to listen for我認爲這裏沒有使用domain socket.因此忽略不計。
/* Abort if there are no listening sockets at all. */這個只是檢查而已,繼續往下看。
而後接下來的幾行代碼採用了dictCreate,還記得以前說過的模板麼?
我找到了個人模板,而後替換幾個參數,讓若干變量得以順利初始化。
listSetFreeMethod(server.pubsub_patterns,freePubsubPattern);設置server.pubsub_patterns->free = freePubsubPattern
listSetMatchMethod(server.pubsub_patterns,listMatchPubsubPattern);設置 server.pubsub_patterns->match = listMatchPubsubPattern
剩下的若干初始化就很簡單,不用多說,代碼以下:
server.cronloops = 0; server.rdb_child_pid = -1; server.aof_child_pid = -1; aofRewriteBufferReset(); server.aof_buf = sdsempty(); server.lastsave = time(NULL); /* At startup we consider the DB saved. */ server.lastbgsave_try = 0; /* At startup we never tried to BGSAVE. */ server.rdb_save_time_last = -1; server.rdb_save_time_start = -1; server.dirty = 0; server.stat_numcommands = 0; server.stat_numconnections = 0; server.stat_expiredkeys = 0; server.stat_evictedkeys = 0; server.stat_starttime = time(NULL); server.stat_keyspace_misses = 0; server.stat_keyspace_hits = 0; server.stat_peak_memory = 0; server.stat_fork_time = 0; server.stat_rejected_conn = 0; server.stat_sync_full = 0; server.stat_sync_partial_ok = 0; server.stat_sync_partial_err = 0; memset(server.ops_sec_samples,0,sizeof(server.ops_sec_samples)); server.ops_sec_idx = 0; server.ops_sec_last_sample_time = mstime(); server.ops_sec_last_sample_ops = 0; server.unixtime = time(NULL); server.mstime = mstime(); server.lastbgsave_status = REDIS_OK; server.repl_good_slaves_count = 0;