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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.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
Sockets TCP如何在解复用中读取IP地址?_Sockets_Networking_Tcp_Network Programming_Ip - Fatal编程技术网

Sockets TCP如何在解复用中读取IP地址?

Sockets TCP如何在解复用中读取IP地址?,sockets,networking,tcp,network-programming,ip,Sockets,Networking,Tcp,Network Programming,Ip,大多数计算机网络书籍在解释TCP/IP协议栈时都提到:当一层接收到其PDU(无论是帧还是段…)时,请执行以下操作: 检查字段,做一些事情,并决定是否将消息传递给其上面的层 如果该层决定将消息传递到其上面的层,则上面的层将在之后再次执行与上一步相同的操作(删除上一层标题) 如果这是真的,那么问题就出现了:TCP如何知道将用于将段移动到其相应套接字的源IP地址(网络层头中的地址) 提前感谢 他们在(介绍性)教科书中所说的关于网络堆栈中的数据包遍历的内容只是教学性的。如果我们看看它是如何实现的,它

大多数计算机网络书籍在解释TCP/IP协议栈时都提到:当一层接收到其PDU(无论是帧还是段…)时,请执行以下操作:

  • 检查字段,做一些事情,并决定是否将消息传递给其上面的层
  • 如果该层决定将消息传递到其上面的层,则上面的层将在之后再次执行与上一步相同的操作(删除上一层标题)
如果这是真的,那么问题就出现了:TCP如何知道将用于将段移动到其相应套接字的源IP地址(网络层头中的地址)

提前感谢

他们在(介绍性)教科书中所说的关于网络堆栈中的数据包遍历的内容只是教学性的。如果我们看看它是如何实现的,它就复杂多了。让我们考虑Linux。
  • Harald Welte的文章总结了不同阶段的数据包遍历
我引用这篇文章的相关部分来回答你的问题

  • IP数据包处理程序是通过net/core/dev.c:dev_add_pack()注册的,从net/ipv4/IP_output.c:IP_init()调用

  • IPv4数据包处理函数为net/IPv4/ip_input.c:ip_rcv()。经过一些初始检查(如果数据包是针对该主机的,…)后,将计算ip校验和。对长度和IP协议版本4进行额外检查。每一个未通过一次健全性检查的数据包都会在此时被丢弃

  • 成功遍历后,将调用net/ipv4/ipv_input.c:ip_rcv_finish()。在ip_rcv_finish()内部,通过调用路由函数net/ipv4/route.c:ip_route_input()来确定数据包的目的地。此外,如果我们的IP数据包有IP选项,它们现在就被处理。根据net/ipv4/route.c:ip_route_input_slow()做出的路由决定,数据包的旅程将通过以下功能之一继续:

    • net/ipv4/ip_input.c:ip_local_deliver():数据包的目的地是本地的,我们必须处理第4层协议并将其传递给用户空间进程

    • net/ipv4/ip_-forward.c:ip_-forward():数据包的目的地不是本地的,我们必须将其转发到另一个网络

    • net/ipv4/route.c:ip_error():发生错误,无法找到此数据包的适当路由表项

    • net/ipv4/ipmr.c:ip_mr_input():这是一个多播数据包,我们必须进行一些多播路由

  • 注意:跳过与Netfilter挂钩相关的一些遍历阶段。所有阶段请参考原始文章


    net/ipv4/in\u input.c:ip\u local\u deliver()
    是我们感兴趣的函数。如上所述,它处理第4层协议并将其传递给用户空间。从Linux内核代码可以看出它是如何实现的,简而言之,假设
    ip\u local\u deliver()
    知道第三层的详细信息是无害的;在UDP的情况下,它是每个应用程序要传递的数据的一部分,因此它被提供给UDP层。但分层并不像某些文本所暗示的那样干净,也不像国家所暗示的那样干净。引擎盖下有很多偷窥的内容。@IbrahimAlnefisi因为你是这个社区的新手,请刷新此链接