C++ 通过TLS向服务器发送HTTP2帧

C++ 通过TLS向服务器发送HTTP2帧,c++,sockets,ssl,http2,C++,Sockets,Ssl,Http2,我正在努力学习HTTP2协议是如何工作的。我看到苹果将其用于推送通知服务器。我使用的是来自的框架规格 作为测试,我编写了应该与该服务器通信的代码。然而,我不断得到的错误,我错过了“设置”帧 我的代码如下: #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #定义套接字错误-1 struct Frame//表示和HTTP2 Frame。 { charlen[24]; 字符类型[8]; 字符标志[8]; 字符标识符[31]; 字符有效载荷[]; }_uuu属性_uuu((压缩)

我正在努力学习HTTP2协议是如何工作的。我看到苹果将其用于推送通知服务器。我使用的是来自的框架规格

作为测试,我编写了应该与该服务器通信的代码。然而,我不断得到的错误,我错过了“设置”帧

我的代码如下:

#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义套接字错误-1
struct Frame//表示和HTTP2 Frame。
{
charlen[24];
字符类型[8];
字符标志[8];
字符标识符[31];
字符有效载荷[];
}_uuu属性_uuu((压缩));
void writeFrame(SSL*SSL)
{
//连接后的第一件事是发送序言。
std::string preference=“PRI*HTTP/2.0\r\n\r\n”;
前言+=“SM\r\n\r\n”;
SSL_write(SSL,preference.c_str(),preference.length());
//现在发送第一帧,也就是设置帧。
Frame*Frame=(Frame*)malloc(sizeof(Frame));
memset(frame,0,sizeof(frame));
int frameSize=100;
memcpy(frame->len,&frameSize,sizeof(frameSize));
memcpy(框架->类型,“设置”,strlen(“设置”);
memcpy(帧->标识符,“设置”,strlen(“设置”);
SSL_write(SSL,frame,sizeof(frame));
//读取服务器响应。
字符缓冲区[10000];
memset(buffer,0,sizeof(buffer));
int dataLen;
而((dataLen=SSL_read(SSL,buffer,sizeof(buffer))>0))
{
int i=0;
而(buffer[i]>=32 | | buffer[i]='\n'| | buffer[i]='\r'){
标准:cout(0)
{
int i=0;
而(buffer[i]>=32 | | buffer[i]='\n'| | buffer[i]='\r'){
std::cout ai_族,结果->ai_类型,结果->ai_协议);
如果(sock==-1)
{
返回-1;
}
sockaddr中的结构sockaddr_;
sockAddr.sin\u addr=重新解释(结果->ai\u addr)->sin\u addr;
sockAddr.sin_family=结果->ai_family;
sockAddr.sinu port=htons(443);
freeaddrinfo(结果);
if(connect(sock,reinterpret_cast(&sockAddr),sizeof(sockAddr))==SOCKET_错误)
{
关闭(袜子);
返回-1;
}
SSL_CTX*CTX=SSL_CTX_new(TLSv1_2_method());
SSL*SSL=SSL_new(ctx);
SSL\u set\u fd(SSL,sock);
SSL_connect(SSL);
writeFrame(ssl);
SSL_-CTX_-free(CTX);
SSL_关机(SSL);
无SSL(SSL);
关闭(袜子);
返回0;
}

如何将
设置
帧和其他帧发送到服务器?我遗漏了什么?

您有几个错误

首先是
数据结构,其中数组字段的长度是错误的。 您似乎以位为单位复制了它们的长度,但在
帧中以字节为单位报告了它们。
您希望这样做:

结构框架{ charlen[3]; 煤焦类型; 字符标志; 字符标识符[4]; 字符有效载荷[]; }
此外,帧的类型不是字符串,也不是标识符

最后,请求的格式完全错误,类似于HTTP/1.1,而HTTP/2格式完全不同,并且基于HPACK


我建议您在编写进一步的代码之前仔细阅读。

PRI*HTTP/2.0\r\n\r\n
(等)-通常,有一个
CRLF
分隔标题选项。最后一个选项得到两个
CRLF
。看起来您为每个选项连接了两个
CRLF
。(我可能是错的,因为我从来没有做过你正在做的事情)。@jww,OP的前言是正确的,正如所定义的。我使用该结构(打包)来编写类型为0x4、标志为0和len为0的设置帧。工作正常,但根本不知道如何编写“标题”帧(类型为5、标志为0x5、len为020、标识符为0001)然后有效负载:
“Accept”:“application/json”
,但不起作用。@Brandon,HEADERS框架需要使用编写。