I am trying to implement my own transport layer protocol in Linux for an experiment. I am going to use socket interface and add my protocol using sock_register. For the proto_ops i can see that the parameters for the sendmsg and recvmsg are (struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags). But there are three types of user api's s开发者_运维问答end, sendto, sendmsg. Of these three only sendmsg contains a parameter for msghdr. I find that the other two api's are incompatible with the parameters supplied by the kernel to my kernel-space sendmsg function. So what happens when we use send and sendto user-space api's? Hope i am clear..
Thanks, Bala
send()
is implemented in terms of sendto()
: send(s, buf, len, flags);
is equivalent to sendto(s, buf, len, flags, NULL, 0);
sendto()
is in turn implemented in terms of sendmsg()
. send(s, buf, len, flags, addr, addr_len);
is implemented with (in terms of the userspace interface):
struct iovec iov = {
.iov_base = buf,
.iov_len = len
};
struct msghdr msg = {
.msg_name = addr,
.msg_namelen = addr_len,
.msg_iov = &iov,
.msg_iovlen = 1,
.msg_control = NULL,
.msg_controllen = 0
};
return sendmsg(s, &msg, flags);
The kernelspace interface is slightly different - eg. you get the kiocb
parameter - but the basic idea is the same. A send()
or sendto()
is converted into a sendmsg()
with a msghdr
that points at a single iovec
that references the buffer.
Assuming you are comfortable with the system call mechanism - start from net/socket.c
and follow the call chains - it's more or less clear.
精彩评论