linux网络收发包,linux发送tcp报文

实现发送系统调用

传输层传输处理

复制传输层

传输层传输

网络层传输处理

相邻子系统

网络设备子系统

fec 网卡驱动发送

总结

实现发送系统调用

send 系统调用的源代码位于文件net/socket.c 中。这个系统调用实际上内部使用了sendto系统调用。我主要做了两件事:

找到内核中实际的套接字,并记录该对象内各个协议栈的函数地址。

构造一个struct msghdr 对象并加载用户传递的任何数据,例如缓冲区地址和数据长度。

//net/socket.c

SYSCALL_DEFINE4(发送,整数

、fd、无效

__user *,buff,size_t

, Len, 未签名

整数

,标志){返回

sys_sendto(fd, buff, len, 标志,

, 0

);}SYSCALL_DEFINE6(.){//1 根据fd查找socket。

sock=sockfd_lookup_light(fd, err, fput_needed); //2.

结构

姆斯格哈德

信息

;

结构

约贝克

车联网

;

iov.iov_base=缓冲区;iov.iov_len=msg.msg_iovlen=1

; msg.msg_iov=iov; msg.msg_flags=标志;

sock_sendmsg(sock, msg, len);} 从源码中可以看到,用户态下使用的send和sendto函数实际上都是通过sendto系统调用来实现的。 (send以方便调用的方式方便地封装。)

sendto系统调用首先根据用户传递的fd句柄号查找实际的socket内核对象。然后将用户请求的所有buff、len、flag 和其他参数打包到struct msghdr 对象中。然后调用sock_sendmsg=__sock_sendmsg==__sock_sendmsg_nosec 。在__sock_sendmsg_nosec中,调用从系统调用进入协议栈。我们来看看它的源代码。

//net/socket.c

静止的

排队

整数

__sock_sendmsg_nosec(.){ .返回

sock-ops-sendmsg(iocb, sock, msg, size);} 这里调用的是sock-ops-sendmsg,实际执行的是inet_sendmsg。 (inet_sendmsg函数的地址是通过socket内核对象的ops成员找到的。该函数是AF_INET协议族提供的通用发送函数。)

一般流程如图所示。

传输层传输处理

复制传输层

进入协议栈inet_sendmsg后,内核找到套接字上特定的协议发送函数。对于TCP 协议,它是tcp_sendmsg,对于UPD,它是udp_sendmsg(也可以通过套接字内核对象找到)。

在此函数中,内核为内核状态申请skb 内存,并将用户发送的数据复制到其中。请注意,如果不满足发送条件,则此时可能不会真正开始发送。大致流程如下:

本文来自网络,不代表服装搭配_服装搭配的技巧_衣服的穿配法_服装搭配网立场,转载请注明出处:https://www.fzdapei.com/317843.html
上一篇
下一篇

为您推荐

返回顶部