当应用程序调用socket函数时,程序会发生系统调用陷入内核态,最终会执行sys_socket函数,那么sys_socket定于在哪儿呢? 答案是SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol) @/net/socket.c 最终会编译成为sys_socket。sys_socket 流程分析 1,socket flags 必要检查 2,调用sock_create(),新建一个socket结构体及相关内容 3,sock_map_fd(),新建一个struct file 并将file的priv data初始化为步骤2创建的socket,这样对文件的操作可以调用socket结构体定义的方法。并关联fd和file 4,返回fd sys_create() -> __sock_create() 流程分析 1,domain域及协议合法性判断 2,sock_alloc() ;分配一个struct socket结构体和inode。并且标明inode是socket类型,这样对inode的操作最终可以调用socket操作。 3,根据输入参数,查找net_families数组(该数组通过inet_init创建),获得域(比如inet,unix)特定的socket创建函数。 4,调用实际create函数,对于inet域是inet_create()。inet_create() 流程分析:static int inet_create(struct net *net, struct socket *sock, int protocol,int kern) @net/ipv4/af_inet.c 1,sock->state = SS_UNCONNECTED;//socket 状态设置 2,查找全局数组inetsw(在inet_init函数中初始化)中对应的协议操作集合,最重要的是struct proto和struct proto_ops,分别用于处理四层和socket相关的内容 3,调用sk_alloc(),分配一个struct sock。并将proto类型的指针指向第二步获得的内容。 4,struct inet_sock 是struct sock的超集,具体参见include/net/inet_sock.h中inet_sock的定义。初始化inet_sock,调用sock_init_data.形成socket和sock一一对应的关系,相互有指针指向对方。 5,最后调用proto中注册的init函数,err = sk->sk_prot->init(sk),如果对应于TCP,其函数指针指向tcp_v4_init_sock。sock_map_fd()流程分析 1,调用sock_alloc_file,分配一个struct file,并将私有数据指针指向socket结构 2,fd_install 对应文件描述符和file
建立过程如下:
(connection-oriented) server 方过程 client 方过程 socket() socket() | | bind() bind() | | listen() | | | accept() send()/recv()
如果socket被置为block式,则connect()一直等到连接建立或出错返回,否则立即返回.
出错时返回-1, 错误码在errno中.
如果读写一个没有建立连接的socket则 返回-1, errno为EBADF.
阅读(1920) | 评论(0) | 转发(0) |