server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind((host, port)) # set maximum number of connections server_socket.listen(5) # log server start print(f"Server started on {host}:{port}")
host, port 分别是地址和端口,例如host="127.0.0.1", port="27019"
structMsgHeader { int32 messageLength; // total message size, including this int32 requestID; // identifier for this message int32 responseTo; // requestID from the original request // (used in responses from the database) int32 opCode; // message type }
flagBits: 前 16 位必须有,我个人的理解是只能设置有实际含义的二进制位,否则,解析器则必须报错,对应原文是 "The first 16 bits (0-15) are required and parsers MUST error if an unknown bit is set."
最后 16 位是可选的,允许设置一些额外的标志位,但代理和其他消息转发器必须在转发消息之前清除任何未知的可选位。
defbyte2string(data, offset): """ Convert byte data to string. :param data: byte data :param offset: pointer to the start of the string :return: pointer to the end of the string and the string """ full_str = "" # cstring end with b'\0' while data[offset] != 0: full_str += chr(data[offset]) offset += 1 return offset+1, full_str
defbyte2int32(data, offset): """ Convert byte data to integer. :param data: byte data :param offset: pointer to the start of the integer :return: pointer to the end of the integer and the integer """ integer = struct.unpack("<i", data[offset:offset+4])[0] return offset+4, integer
defbyte2int64(data, offset): """ Convert byte data to integer. :param data: byte data :param offset: pointer to the start of the integer :return: pointer to the end of the integer and the integer """ integer = struct.unpack("<q", data[offset:offset+8])[0] return offset+8, integer
defbyte2document(data, offset): """ Covert byte data to dict object in Python :param data: byte data :param offset: pointer to the start of the document :return: offset and decoded document result """ doc_length = struct.unpack("<i", data[offset: offset+4])[0] document = bson.decode(data[offset: offset+doc_length]) offset += doc_length return offset, document
defbyte2uint32(data, offset): """ Convert byte data to unsigned integer. :param data: byte data :param offset: pointer to the start of the integer :return: pointer to the end of the integer and the integer """ integer = struct.unpack("<I", data[offset:offset+4])[0] return offset+4, integer
defcrc32_checksum(raw_data, checksum): """ Calculate the CRC32 checksum of the given data and compare it with the given checksum. :param raw_data: Total data except the checksum :param checksum: The expected checksum :return: """ computed_checksum = zlib.crc32(raw_data) & 0xFFFFFFFF return computed_checksum == checksum