Previous article: juejin.cn/post/695623…

RESP3

Let’s take a look at all of them:

NULL

Represents *-1\r\n or $-1\r\n in resp2

_\r\n
Copy the code

Double

And 1.23 \ r \ nCopy the code

Boolean

#t\r\n
#f\r\n
Copy the code

Binary safe error

! 21\r\nSYNTAX invalid syntax\r\nCopy the code

Verbatim string

=15<CR><LF>
txt:Some string<CR><LF>
Copy the code

Verbatim string

=15<CR><LF>
txt:Some string<CR><LF>
Copy the code

Map

%2<CR><LF>
+first<CR><LF>
:1<CR><LF>
+second<CR><LF>
:2<CR><LF>
Copy the code

Set

~5<CR><LF>
+orange<CR><LF>
+apple<CR><LF>
#t<CR><LF>
:100<CR><LF>
:999<CR><LF>
Copy the code

Hello

When establishing a connection, return the server name, version, and so on

#Send this, and you can switch to RESP3
HELLO 3
Copy the code

receive

  1. serverThe end receives the command first stored in the client objectquerybufInput buffer
  2. Then start parsing the command, the arguments; And stored in the client objectArgv (parameter object), argc(parameter number)

Let’s talk about the second, specific parsing process:

  1. Number of parsed request parameters
  2. Loop through each request parameter

Number of parameters

ProcessMultibulkBuffer, then the first character * must be identified:

// The number of arguments to read into the command
/ / such as $3 * 3 \ r \ n \ r \ nSET \ r \ n... Will make C ->multibulklen = 3
if (c->multibulklen == 0) {
  redisAssertWithInfo(c,NULL,c->argc == 0);

  // Check the contents of buffer first "\r\n"
  newline = strchr(c->querybuf,'\r'); .// The first character of the protocol must be '*'
  redisAssertWithInfo(c,NULL,c->querybuf[0] = =The '*');
  // Take the number of arguments after * and before \r\n and save it to ll
  // For *3\r\n, then ll will be equal to 3
  // ----> < span style = "box-sizing: border-box! Important
  ok = string2ll(c->querybuf+1,newline-(c->querybuf+1),&ll);
  // The number of parameters exceeds the limit
  if(! ok || ll >1024*1024) {
    addReplyError(c,"Protocol error: invalid multibulk length");
    setProtocolError(c,pos);
    return REDIS_ERR;
  }

  // The position after the number of arguments
  // For *3\r\n$3\r\nSET\r\n... Speaking,
  // pos points to *3\r\n$3\r\nSET\r\n...
  / / ^
  // |
  // pos
  // Record the resolved location offset
  pos = (newline-c->querybuf)+2;
  // if ll <= 0, this command is a blank command.// Set the number of parametersc->multibulklen = ll; . }Copy the code

Cyclic parsing parameter

$3\r\nSET\r\n

// Read the length of the argument
if (c->bulklen == - 1) {
  // Make sure "\r\n" exists
  newline = strchr(c->querybuf+pos,'\r'); .// Make sure the protocol conforms to the format of the argument by checking the $...
  / / such as $3 \ r \ nSET \ r \ n
  if(c->querybuf[pos] ! ='$') {
    return REDIS_ERR;
  }

  // Read the length
  // For example, $3\r\nSET\r\n will set ll to 3
  ok = string2ll(c->querybuf+pos+1,newline-(c->querybuf+pos+1),&ll); .// Locate to the beginning of the argument
  / / such as
  // $3\r\nSET\r\n...
  / / ^
  // |
  // pos
  pos += newline-(c->querybuf+pos)+2; .// The length of the argument
  c->bulklen = ll;
}
Copy the code

After parsing out the length of the argument string:

  1. Creating a string object
  2. updatemultibulklen.multibulklen--

When multiBulklen is updated to 0, the parameters are resolved.