有没有办法可以启动更高级别的连接,即 http 连接,然后在某个时候将其“降级”到较低层或 tcp?基本上,一旦使用 http 建立连接,我希望能够抓住套接字并将其与我自己的自定义协议一起使用。
答案1
基本上,一旦使用 http 建立连接,我希望能够抓住套接字并将其与我自己的自定义协议一起使用
在这种情况下,您不会“降级”到较低的 OSI 层。相反,您可以定义自己的应用程序级协议,该协议首先由类似于 HTTP 的内容组成,然后是您需要的任何内容。OSI 层只是一种抽象的思维(即在第 4 层 TCP 上处理字节,而不是在第 7 层处理结构化消息)。
至于使用现有的 HTTP 库实现自己的协议:是否可行以及如何实现完全取决于 HTTP 库。有些库会保留底层 TCP 套接字,有些库可能允许开发人员直接处理它。有些库允许开发人员仅将 HTTP 请求创建为字符串并从字符串解析 HTTP 响应,并将 TCP 套接字的控制权完全掌握在开发人员手中。
答案2
有两个答案,一个针对一般情况,一个针对 HTTP。而且这还取决于您最初如何创建 HTTP“连接”。
大多数操作系统仅提供 TCP/UDP 层之前的抽象(套接字),而上面的所有其他内容(即应用层协议)通常由应用程序处理。因此,当您使用 SSH 客户端、SMTP 客户端或 IRC 客户端时,应用程序始终可以“下拉”到原始 TCP 流,因为这就是应用程序有首先。应用程序本身在操作系统提供的 TCP 连接之上构建一切。
HTTP 如此广泛地应用,但它却在某种程度上是个例外,它经常具有共享库(例如 libcurl 或 python-requests)甚至操作系统提供的抽象(例如 WinHTTP)。
libcurl 等库是应用程序的一部分,仅基于操作系统提供的相同 TCP 套接字构建。其中一些库允许访问底层套接字;其他则不允许。无论如何,这些都是可选的——有些程序仍然喜欢毫无理由地手动操作 HTTP 客户端。
但其他HTTP 之所以例外,是因为应用程序才不是通常首先启动“HTTP 连接”。HTTP 是一种无状态协议;大多数 HTTP 客户端库使用请求/响应作为抽象,并且只按需打开 TCP 连接。多个请求可能共享底层 TCP 连接,也可能不共享。(协议可能是 HTTP/1.1,也可能是 HTTP/2。)
换句话说,通常只是不是当您请求连接时,它已经不再是低层连接了。
也有例外。如今许多浏览器和网站都使用网络套接字,它以普通的 HTTP 请求开始,但之后会切换到双工 TCP 类流连接。(但这不一定是原始 TCP – websocket 可能仍使用 TLS,并且它们可能有自己的框架层。我认为 HTTP/2 上的 websocket 继承了它的框架。)