gpt4 book ai didi

c++ - 难以理解协议(protocol)定义

转载 作者:行者123 更新时间:2023-11-29 14:38:11 24 4
gpt4 key购买 nike

我正在阅读 Postgresql 有线协议(protocol)并且在实现一个与简单查询相关的部分时遇到了问题,其中 spec说:

Query (F)
Byte1('Q')
Identifies the message as a simple query.

Int32
Length of message contents in bytes, including self.

String
The query string itself.

我在 C++ 中想出了以下内容:

(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >) $0 = size=31 {
[0] = 'Q'
[1] = '\0'
[2] = '\0'
[3] = '\0'
[4] = '\x1f'
[5] = 's'
[6] = 'e'
[7] = 'l'
[8] = 'e'
[9] = 'c'
[10] = 't'
[11] = ' '
[12] = '*'
[13] = ' '
[14] = 'f'
[15] = 'r'
[16] = 'o'
[17] = 'm'
[18] = ' '
[19] = 'd'
[20] = 'e'
[21] = 'p'
[22] = 'a'
[23] = 'r'
[24] = 't'
[25] = 'm'
[26] = 'e'
[27] = 'n'
[28] = 't'
[29] = 's'
[30] = '\0'
}

但我总是从服务器收到错误:

EJSERRORC08P01Minvalid message formatFpqformat.cL652Rpq_getmsgendETSFATALC08P01Minvalid frontend message type 0Fpostgres.cL484RSocketBackend

在这一点上,我厌倦了在服务器上抛出此 vector 的不同版本以始终获得相同的结果,因此我认为我对规范的解释是错误的。你能用代码告诉我这将如何完成吗?不是生成消息的算法,只是一条有效消息。

最佳答案

因为你不分享你的代码,我不能说你错在哪里。

你的消息很好,除了长度应该是 30 ('\x1e') 而不是 31 ('\x1f') – 根据 the documentation ,“消息类型字节”不计入。

我在 Linux 上用 C 尝试过,它对我有用。

我用 send() 通过 PQsocket() 得到的套接字发送消息,我得到的响应包括:

  1. 一个 RowDescription 消息(类型 'T')描述列。

  2. 每个返回的列一个 DataRow 消息(类型 'D')。

  3. 一个 Close 消息(类型 'C')关闭语句。

  4. 一条ReadyForQuery(类型'Z')消息。

作为记录,这里是我使用的 C 代码:

#include <libpq-fe.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>

#define BUFSIZE 1000

int main(int argc, char **argv) {
/* PostgreSQL database connection */
PGconn *conn;
/* socket for the database connection */
int s;
/* simple select statement to send over the socket */
unsigned char stmt[] = "Q\0\0\0\030select * from amaaa";
/* buffer for the server response */
unsigned char buf[BUFSIZE];
ssize_t len, i;

/* connect to the database */
conn = PQconnectdb("");
if (conn == NULL)
{
fprintf(stderr, "Out of memory connecting to PostgreSQL.\n");
return 1;
}
if (PQstatus(conn) != CONNECTION_OK)
{
fprintf(stderr, "%s\n", PQerrorMessage(conn));
PQfinish(conn);
return 1;
}

/* get the TCP socket that corresponds to the connection */
if ((s = PQsocket(conn)) <= 0)
{
fprintf(stderr, "Connection is not open.\n");
PQfinish(conn);
return 1;
}

/* send the simple select statement */
if (-1 == send(s, stmt, sizeof(stmt), 0))
{
perror("Error in send(2)");
PQfinish(conn);
return 1;
}

/*
* The following is oversimplified.
* In reality, you'd have to call recv(2) until you have
* the complete response.
* But I don't want to bother with analyzing the response
* and hope that it comes in a single packet.
*/

/* receive the response */
if (-1 == (len = recv(s, buf, BUFSIZE, MSG_WAITALL)))
{
perror("Error in recv(2)");
PQfinish(conn);
return 1;
}

/* print the server response */
for (i=0; i<len; ++i) {
if (buf[i] >= ' ' && buf[i] <= 'z')
printf("%02X(%c) ", buf[i], buf[i]);
else
printf("%02X ", buf[i]);
}
printf("\n");

/* close the database connection */
PQfinish(conn);

return 0;
}

关于c++ - 难以理解协议(protocol)定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41063433/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com