除了数据之外,还必须在应用程序、传输层和 Internet 层之间传输一些元数据。
从技术上讲,元数据如何在层之间进行通信是一个实现细节。在实践中,应用层几乎总是使用 berkerly 套接字 API 的一些变体来与传输层通信。
对于 TCP 客户端,目标 IP 和端口作为“连接”API 调用的一部分指定给传输层。对于 UDP 客户端,可以使用“连接”来创建伪连接,或者可以使用“sendto”api 调用在每个数据包的基础上指定目标 IP 和端口。
对于 TCP 服务器,应用程序可以在接受连接后调用 getpeername 来读取 IP 和端口。UDP 服务器可以通过使用 recvfrom API 调用读取数据包来读取每个数据包的 IP 和端口。
不幸的是 sendto 和 recvfrom 有一个设计缺陷。它们只传递远程地址,而不是本地地址,这会导致多宿主主机上的服务器出现问题。服务器可能会从错误的 IP 地址发送回复,导致它们被网络或客户端丢弃。有更新的 API 可以解决这个问题,但细节因操作系统而异。
传输层将依次将传出数据包的 IP 地址通知 Internet 层,而 Internet 层将传入数据包的 IP 地址通知传输层。由于传输层和 Internet 层通常都是 TCP/IP 堆栈的一部分,因此如何完成此操作的细节是堆栈内部的实现细节。
x-forwarded-for 是 http 代理使用的 http 标头。代理将使用 getpeername 检索客户端 IP 地址,然后将其编码为 http 标头以将其传递给下一个服务器。