前言:在前面的文章中介紹了協(xié)議無(wú)關(guān)層和系統(tǒng)調(diào)用接口層。當(dāng)用戶態(tài)程序調(diào)用sendto()和recvfrom()來(lái)發(fā)送和接收數(shù)據(jù)時(shí),其中的過(guò)程是怎么樣的呢?又是經(jīng)過(guò)了幾次數(shù)據(jù)拷貝呢?這篇重點(diǎn)說(shuō)明這兩個(gè)接口,接著上篇來(lái)說(shuō)明數(shù)據(jù)傳輸?shù)倪^(guò)程。
1. sendto()
在上一篇中,我們知道,當(dāng)在應(yīng)用中調(diào)用sendto()發(fā)送函數(shù)時(shí),就會(huì)調(diào)用到系統(tǒng)調(diào)用sys_sendto,在socket.c文件中,我們找到了這個(gè)系統(tǒng)調(diào)用的實(shí)現(xiàn)。
SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
unsigned, flags, struct sockaddr __user *, addr,
int, addr_len)
首先根據(jù)文件描述符找到對(duì)應(yīng)的socket結(jié)構(gòu);
sock = sockfd_lookup_light(fd, &err, &fput_needed);
if (!sock)
goto out;
然后填充要發(fā)送的消息的消息頭,包括用戶態(tài)數(shù)據(jù)起始地址,長(zhǎng)度等信息。
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;
之后把相關(guān)的地址信息copy到內(nèi)核態(tài)
最后進(jìn)行發(fā)送:
err = sock_sendmsg(sock, &msg, len);
||
__sock_sendmsg(&iocb, sock, msg, size);
||
sock->ops->sendmsg(iocb, sock, msg, size);
到這里,我們看到調(diào)用到了協(xié)議族注冊(cè)的發(fā)送函數(shù),如果是DGRAM類型的socket,對(duì)應(yīng)的INET族的發(fā)送函數(shù)是--inet_sendmsg()。我們繼續(xù)沿著這條線往下走,在INET族中,DGRAM類型對(duì)應(yīng)的就是UDP協(xié)議,所以,最終會(huì)調(diào)用到udp_sendmsg()中。
接下來(lái)看一下這個(gè)函數(shù),在這里不打算仔細(xì)說(shuō)這個(gè)函數(shù)(暫時(shí)還真說(shuō)不清。。。太龐大了!)。只關(guān)心用戶數(shù)據(jù)是怎么拷貝到內(nèi)核空間,組裝成udp報(bào)文的。
關(guān)于函數(shù)最開(kāi)始的很多工作,先跳過(guò),直接到標(biāo)簽do_append_data處:
首先確認(rèn)了得到用戶態(tài)數(shù)據(jù)包的處理函數(shù),然后就開(kāi)始添加數(shù)據(jù)頭。
getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
err = ip_append_data(sk, getfrag, msg->msg_iov, ulen,
sizeof(struct udphdr), &ipc, &rt,
corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
其實(shí),拷貝用戶態(tài)的數(shù)據(jù)就在getfrag函數(shù)實(shí)現(xiàn)的。
static __inline__ int udplite_getfrag(void *from, char *to, int offset,
int len, int odd, struct sk_buff *skb)
{
return memcpy_fromiovecend(to, (struct iovec *) from, offset, len);
}
其他的就先不多說(shuō)了,留到分析傳輸層UDP的時(shí)候再細(xì)說(shuō)。sendto也就說(shuō)到這里。
新聞熱點(diǎn)
疑難解答
圖片精選