------------------------------------------------------------------------------------------
以下是我根据 linux-2.6.23.9版本内核源代码所做阅读笔记,属个人兴趣而为,希望找到有共同兴趣
的朋友一起讨论和研究,有谬误之处,笔者水平有限,欢迎大家拍砖:)
------------------------------------------------------------------------------------------
|----------------------------------|
应用层
|----------------------------------|
BSD
Socket层
|----------------------------------|
Inet
Socket层
|----------------------------------|
IP层
|----------------------------------|
数据链路/硬件层
|----------------------------------|
IP层: IP协议栈的实现,完成路由的查找过程(主要处理skb)
Inet Socket层: 对IP包进行分组排序,实现QoS,传输层协议TCP/UDP协议栈的实现
使用sock{}类型数据来管理会话,数据主要放在sk_buff结构中
BSD
Socket: 对于BSD Socket相关调用的实现,主要使用socket{}结构来存放连接
数据主要是放在msghdr{}结构中
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;
};
msg_name: socket的名字,通常用NULL初始化
msg_iov: 发送或接收缓冲区地址数据
msg_iovlen: msg_iov中保存的数据包的个数
msg_flags: 保存数据接收时的控制标志,可以由应用
层控制,如果设置为MSG_DONTWAIT,则表示使用非阻塞方式收取数据包
struct
iovec
{
void __user *iov_base;
__kernel_size_t iov_len;
};
实际上,msghdr中存储的iovec是一个数组,每个iovec都有自己单独的数据起始地址和
数据长度,以下的代码将skb->data(kdata)用copy_to_user传到用户态,用户态的BSD
Socket接口将分段的数据进行合并,组成一段连续的内存buffer.
int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int
len)
{
while (len > 0) {
if (iov->iov_len) {