send、sendto与sys_sendto之间的关系
来源:互联网 发布:网络大电影演员成本 编辑:程序博客网 时间:2024/05/27 00:31
sys_sendto()
sys_socketcall() --> sys_sendto()
asmlinkage long sys_sendto(
int fd,
void __user *buff, size_t len,
unsigned flags,
struct sockaddr __user *addr, int addr_len)
{
struct socket *sock;
char address[MAX_SOCK_ADDR];
int err;
struct msghdr msg;
struct iovec iov;
int fput_needed;
struct file *sock_file;
sock_file = fget_light(fd, &fput_needed);
err = -EBADF;
if (!sock_file)
goto out;
sock = sock_from_file(sock_file, &err);
if (!sock)
goto out_put;
iov.iov_base = buff;
iov.iov_len = len;
msg.msg_name = NULL;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_namelen = 0;
if (addr) {
err = move_addr_to_kernel(addr, addr_len, address);
if (err < 0)
goto out_put;
msg.msg_name = address;
msg.msg_namelen = addr_len;
}
if (sock->file->f_flags & O_NONBLOCK)
flags |= MSG_DONTWAIT;
msg.msg_flags = flags;
err = sock_sendmsg(sock, &msg, len);
out_put:
fput_light(sock_file, fput_needed);
out:
return err;
}
在内核的实现中,send和sendto系统调用最终都会调用到内核函数:
asmlinkage long sys_sendto(
int fd,
void __user *buff, size_t len,
unsigned flags,
struct sockaddr __user *addr, int addr_len)
fd socket文件描述符
buff 指向需要发送的数据
len 需要发送的数据的长度
flags 标志位
addr 数据报文要发送的对方端点的地址信息
addr_len 地址信息的长度
在send系统调用中,参数addr被置为NULL,addr_len为0。sys_sendto首先根据传入的描述符fd,找到对应的struct socket结构体。然后构建内核的消息结构struct msghdr:
内核的消息结构struct--msghdr:
struct msghdr {
void *msg_name;
int msg_namelen;
struct iovec *msg_iov;
__kernel_size_t -msg_iovlen;
void *msg_control;
__kernel_size_t -msg_controllen;
unsigned msg_flags;
};
msghdr->msg_name
msghdr->msg_namelen
-----------------------------------
msg_name和msg_namelen就是数据报文要发向的对端的地址信息(即sendto系统调用中的addr和addr_len)。当使用send时,它们的值为NULL和0。
msghdr->msg_iov
-----------------------------------
msg_iov的定义如下:
struct--iovec {
void __user *iov_base;
__kernel_size_t iov_len;
};
表示存放待发送数据的一个缓冲区,iov_base是缓冲区的起始地址,指向message, iov_len是缓冲区的长度,指向length。
msghdr->msg_iovlen
-----------------------------------
msg_iovlen是缓冲区的数量,对于sendto和send来讲,msg_iovlen都是1。
msghdr->msg_flags
msghdr->msg_control
msghdr->msg_controllen
-----------------------------------
msg_flags即为传入的参数flags,现在暂时不过多的关注flags的应用。
msg_control和msg_controllen暂时不关注。
sys_sendto构建完这些后,调用sock_sendmsg继续执行发送流程,传入参数为struct msghdr和数据的长度。忽略中间的一些不重要的细节,sock_sendmsg继续调用__sock_sendmsg(),__sock_sendmsg()最后调用struct socket->ops->sendmsg,即对应套接字类型的sendmsg()函数,所有的套接字类型的sendmsg()函数都是inet_sendmsg(),该函数首先检查本地端口是否已绑定,无绑定则执行自动绑定,而后调用具体协议的sendmsg函数。
asmlinkage long sys_sendto(
int fd,
void __user *buff, size_t len,
unsigned flags,
struct sockaddr __user *addr, int addr_len)
{
struct socket *sock;
char address[MAX_SOCK_ADDR];
int err;
struct msghdr msg;
struct iovec iov;
int fput_needed;
struct file *sock_file;
sock_file = fget_light(fd, &fput_needed);
err = -EBADF;
if (!sock_file)
goto out;
sock = sock_from_file(sock_file, &err);
if (!sock)
goto out_put;
iov.iov_base = buff;
iov.iov_len = len;
msg.msg_name = NULL;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_namelen = 0;
if (addr) {
err = move_addr_to_kernel(addr, addr_len, address);
if (err < 0)
goto out_put;
msg.msg_name = address;
msg.msg_namelen = addr_len;
}
if (sock->file->f_flags & O_NONBLOCK)
flags |= MSG_DONTWAIT;
msg.msg_flags = flags;
err = sock_sendmsg(sock, &msg, len);
out_put:
fput_light(sock_file, fput_needed);
out:
return err;
}
在内核的实现中,send和sendto系统调用最终都会调用到内核函数:
asmlinkage long sys_sendto(
int fd,
void __user *buff, size_t len,
unsigned flags,
struct sockaddr __user *addr, int addr_len)
fd socket文件描述符
buff 指向需要发送的数据
len 需要发送的数据的长度
flags 标志位
addr 数据报文要发送的对方端点的地址信息
addr_len 地址信息的长度
在send系统调用中,参数addr被置为NULL,addr_len为0。sys_sendto首先根据传入的描述符fd,找到对应的struct socket结构体。然后构建内核的消息结构struct msghdr:
内核的消息结构struct--msghdr:
struct msghdr {
void *msg_name;
int msg_namelen;
struct iovec *msg_iov;
__kernel_size_t -msg_iovlen;
void *msg_control;
__kernel_size_t -msg_controllen;
unsigned msg_flags;
};
msghdr->msg_name
msghdr->msg_namelen
-----------------------------------
msg_name和msg_namelen就是数据报文要发向的对端的地址信息(即sendto系统调用中的addr和addr_len)。当使用send时,它们的值为NULL和0。
msghdr->msg_iov
-----------------------------------
msg_iov的定义如下:
struct--iovec {
void __user *iov_base;
__kernel_size_t iov_len;
};
表示存放待发送数据的一个缓冲区,iov_base是缓冲区的起始地址,指向message, iov_len是缓冲区的长度,指向length。
msghdr->msg_iovlen
-----------------------------------
msg_iovlen是缓冲区的数量,对于sendto和send来讲,msg_iovlen都是1。
msghdr->msg_flags
msghdr->msg_control
msghdr->msg_controllen
-----------------------------------
msg_flags即为传入的参数flags,现在暂时不过多的关注flags的应用。
msg_control和msg_controllen暂时不关注。
sys_sendto构建完这些后,调用sock_sendmsg继续执行发送流程,传入参数为struct msghdr和数据的长度。忽略中间的一些不重要的细节,sock_sendmsg继续调用__sock_sendmsg(),__sock_sendmsg()最后调用struct socket->ops->sendmsg,即对应套接字类型的sendmsg()函数,所有的套接字类型的sendmsg()函数都是inet_sendmsg(),该函数首先检查本地端口是否已绑定,无绑定则执行自动绑定,而后调用具体协议的sendmsg函数。
- send、sendto与sys_sendto之间的关系
- socket的send与sendto
- send和sendto的区别
- send()、sendto()和recv()、recvfrom()的使用
- sys_sendto的函数实现
- send/sendto/sendmsg
- send,recv,sendto,recvfrom
- send,recv,sendto,recvfrom
- send,recv,sendto,recvfrom
- send,recv,sendto,recvfrom
- send,recv,sendto,recvfrom
- send,recv,sendto,recvfrom
- send,recv,sendto,recvfrom
- send,recv,sendto,recvfrom
- send,recv,sendto,recvfrom
- send revc sendto revcfrom
- send recv sendto recvfrom
- send , recv , sendto , recvfrom
- 深入Java集合学习系列:HashMap的实现原理
- 面试基础
- acm——贪心算法(There is a pile of n wooden sticks)
- 导航电子地图数据中POI搜索技术原理之六
- const关键字浅析
- send、sendto与sys_sendto之间的关系
- 【五子棋AI】启发算法——开局库
- 导航电子地图数据中POI搜索技术原理之七
- Linux time subsystem 详解(1) ----概述
- Android应用程序内存优化
- 一级汉字编码及常用二级汉字编码表
- 我的第一个网站(imokf.com)
- Table布局width设置为百分比无效问题
- 请仅用一笔画四根直线,将下图9各点全部连接