Step redis client connects to the server

Most client and the server are connected to the same, redis-cli connection to the server is mainly divided into two stages, the connection request phase and data transfer phase. Specifically redis-cli do are:

1, connection is established in a socket manner;

2, select the appropriate database;

3, the client sends command encoding;

4, the client transmits the encoded data (Write);

5, the server response data received (Read);

6, parsing the received data.

The following were analyzed according to what made the source code for the client.

/ * Interactive MODE When the Start Command IS NO Provided * /
IF (argc == 0 && config.eval!) {
/ * In the Ignore SIGPIPE Interactive MODE Reconnect to A * Force /
Signal (SIGPIPE, SIG_IGN);

/ * Note that in Not ABORT mODE WE do the repl oN Connection error.
* a new new attempt for Every Will BE Performed * Send Command /.
cliConnect (0);
the repl ();
}
the above code is redis-cli section on the main function of the interactive mode, and consists essentially of the repl cliConnect, wherein the former is responsible for connection to the server, which is responsible for data transmission.

Establish a connection
on a client connection to the server, we know that major steps are divided,

1, create a socket (have a fixed pattern);

2. The set ip and port number, the server Connet;

Well, this has always been the traditional approach, we look at how it redis do it?

It first defines a redis the context structure, comprising a request and the response data information and status information is as follows:

typedef struct redisContext {
int ERR;
char The errstr [128];
int FD;
int the flags;
char * OBUF;
redisReader * Reader;
enum redisConnectionType connection_type;
struct timeval * timeout;
struct {
char * Host;
char * SOURCE_ADDR;
int Port;
} TCP;

struct {
char * path;
} unix_sock;
} redisContext;
ERR, variable errstr definition at abnormal receive data, fd sockfd created for the client, obuf coding command client, reader for the server to return data. And performs initialization, defined tcp, fd and other information cliConnect.

Take a look at the operation of cliConnect

* Connect to the server. It is possible to pass certain flags to the function:
* CC_FORCE: The connection is performed even if there is already
* a connected socket.
* CC_QUIET: Don't print errors if connection fails. */
static int cliConnect(int flags) {
if (context == NULL || flags & CC_FORCE) {
if (context != NULL) {
redisFree(context);
}

if (config.hostsocket == NULL) {
context = redisConnect(config.hostip,config.hostport);
} else {
context = redisConnectUnix(config.hostsocket);
}
...

anetKeepAlive(NULL, context->fd, REDIS_CLI_KEEPALIVE_INTERVAL);

/* Do AUTH and select the right DB. */
if (cliAuth() != REDIS_OK)
REDIS_ERR return;
(! cliSelect () = REDIS_OK) IF
return REDIS_ERR;
}
return REDIS_OK;
}
the flags used in the case that the client has connected to the server, whether the connection can, 0 indicates no connection, 1 if allowed connection (will be used when changing client server log).

redisConnect defines the context of ip, port; redisContextInit call initialization string, call redisContextConnectTcp (c, ip, port, NULL) to complete the socket connection.

Since the connection has been completed, cliSelect invoke the command

reply = redisCommand (context, "SELECT % d", config.dbnum);
selected from the database No. 0 (default).

Data transmission
in the repl () using the processing tool linenoise input line, a character string part is divided cliSplitArgs, parameter processing part is issueCommandRepeat. It calls redisAppendCommandArgv encode parameters passed to the obu context; cliReadReply call for data decoding received by the client; call redisGetReply (in cliReadReply) is responsible for transmitting the underlying I / O data.

int redisGetReply(redisContext *c, void **reply) {
int wdone = 0;
void *aux = NULL;

/* Try to read pending replies */
if (redisGetReplyFromReader(c,&aux) == REDIS_ERR)
return REDIS_ERR;

/* For the blocking context, flush output buffer and read reply */
if (aux == NULL && c->flags & REDIS_BLOCK) {
/* Write until done */
do {
if (redisBufferWrite(c,&wdone) == REDIS_ERR)
return REDIS_ERR;
} while (!wdone);

/* Read until there is a reply */
do {
if (redisBufferRead(c) == REDIS_ERR)
return REDIS_ERR;
if (redisGetReplyFromReader(c,&aux) == REDIS_ERR)
return REDIS_ERR;
} while (aux == NULL);
}

/ * The Set Object Reply * /
IF (! = NULL Reply) = AUX Reply *;
return REDIS_OK;
}
mainly redisBufferWrite and redisBufferRead, respectively, to the I / Obuf write and read data. redisGetReplyFromReader responsible for decoding the received data.

Summary:
1, Redis-cli on the basis of basic client-side programming, an increase of Context definition, you can know the good and bad types of data, data.

2, an increase of encoding and decoding functions, general codec function can make the data more secure, maybe it is because it was conducted codec.

3, or to achieve some specific need further study.

 
--------------------- 

Guess you like

Origin www.cnblogs.com/ly570/p/10961763.html