Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
试图通过python套接字升级到http2_Python_Sockets_Ssl - Fatal编程技术网

试图通过python套接字升级到http2

试图通过python套接字升级到http2,python,sockets,ssl,Python,Sockets,Ssl,我正在尝试使用python套接字升级到http/2.0。我已经尝试过这样使用升级头:Connection:upgrade然后upgrade:h2c。这使服务器以http/1.1 200 OK响应进行响应。我现在正试图通过ssl模块使用ALPN。 这是通过ALPN尝试的代码: def connect_socket(self): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) context =

我正在尝试使用python套接字升级到http/2.0。我已经尝试过这样使用升级头:
Connection:upgrade
然后
upgrade:h2c
。这使服务器以http/1.1 200 OK响应进行响应。我现在正试图通过
ssl
模块使用ALPN。
这是通过ALPN尝试的代码:

 def connect_socket(self):

        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        context = ssl.create_default_context()

        context.set_alpn_protocols(['h2c'])

        while True:
            try:
                sock.connect(("twitter.com", 443))
                sock = context.wrap_socket(sock)
                return sock
                
            except:
                pass
这只是挂在
上下文中。包装套接字(sock)
。如果我去掉上下文,只使用ssl.wrap_socket()一切正常,我就可以很好地使用HTTP/1.1。服务器确实支持它,因为使用PyCurl的详细模式,我可以看到它使用HTTP/2。
我试过使用
h2c
http/2.0
h2

打印我得到的异常结果是:

[WinError 10056] A connect request was made on an already connected socket
仍不升级的最新代码:

def connect_socket(self):

        while True:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

            context = ssl.create_default_context()

            context.set_alpn_protocols(['h2c'])

            context.check_hostname = False
            try:
                sock.connect(("twitter.com", 443))
                sock = context.wrap_socket(sock)
                return sock

            except Exception as e:
                sock.close()
                print(e)
这将返回一个无错误的套接字,然后发送此请求:

def test_send_data(self, sock):
        
        unencoded_string = 'GET /noah HTTP/1.1\r\nHost: twitter.com\r\nConnection: keep-alive\r\n\r\n'
        
        sock.send(unencoded_string.encode())
这很好,响应的重要部分是:

HTTP/1.1 200 OK\r\ncache-control: no-cache, no-store, must-revalidate,

我的问题是:为什么它只是挂起,我如何修复它?

我认为您的一些异常处理给了您错误的提示。如果遇到异常,您可能会再次尝试连接,Windows会在某个时候抱怨尝试连接到未关闭的套接字

HTTP/2的ALPN协议应设置为
h2
,然后运行代码时出现错误:

ValueError: check_hostname requires server_hostname
添加该参数后,我能够从服务器获得响应,Python说连接是H2:

导入套接字
导入ssl
def connect_h2_插槽(主机):
sock=socket.socket(socket.AF\u INET,socket.sock\u流)
context=ssl.create\u default\u context()
context.set_alpn_协议([“h2”])
sock.connect((主机,443))
sock=context.wrap\u套接字(sock,server\u hostname=host)
回程短袜
s=连接h2插座(“twitter.com”)
打印(“选定协议:”,s.选定协议()
打印(s.recv())
运行此命令将为我产生以下结果:


'h2'
是否改变了与
'h2c'
相反的任何东西?不,原来我得到了一个例外。查看编辑后的问题了解详细信息。while循环有什么用?我相信你首先遇到了一个不同的异常,它会传递异常,然后当你再次连接时,你会发现你已经在套接字上了,因为你处于循环中。哎哟,不小心在最近的一条评论之前删除了我的评论,这条评论对后人来说是“pass
server\u hostname=“twitter.com”“
包装\u套接字
并使用h2作为协议。应该没问题。摆脱while循环,不要传递异常。“原来你是对的。使用h2,不检查主机名挂起,但传递服务器的主机名将起作用。在那之后,我的下一个错误实际上是在recv函数中,我正在寻找\r\n\r\n从读取循环中断并返回字节字符串。我刚刚意识到这将不起作用,如果您愿意,在打印套接字recv数据后,发布答案,我将接受+up-vote。您是否知道如何通过HPACK解压缩响应?我似乎越来越多了errors@Noah我不知道HPACK是什么,最好还是单独问一个问题!
Selected protocol: h2
b'\x00\x00\x06\x04\x00\x00\x00\x00\x00\x00\x04\x00\x01\x00\x00'