深入理解socket

      一个socket代表了通信链路的一端,存储或指向与链路有关的所有信息。Linux提供了创建socket的一个系统调用,通过该系统调用,能够得到一个用来访问套接字的描述符:
         #include <sys/types.h>
         #include <sys/socket.h>
         int socket( int domain, int type, int protocol );
      内核中的系统调用函数原型是在net/socket.c 1180行:
         asmlinkage long sys_socket( int family, int type, int protocol );
      该函数主要做了两件事情:创建一个代表通讯端点的结构体struct socket,将这个结构映射到一个文件描述符上,最后将这个描述符返回,也就是我们调用socket得到的套接字描述符。
 下面是Linux内核中对结构socket的定义(不同操作系统间,对该结构的定义会有差异):
 struct socket {
     socket_state            state;
     unsigned long           flags;
     struct proto_ops        *ops;
     struct fasync_struct    *fasync_list;
     struct file             *file;
     struct sock             *sk;
     wait_queue_head_t       wait;
     short                   type;
 };
         
       state是一个内部状态标志:
       typedef enum {
           SS_FREE = 0,         /* 未分配 */
           SS_UNCONNECTED,      /* 未连接 */
           SS_CONNECTING,       /* 正在连接当中 */
           SS_CONNECTED,        /* 已经连向一个套接字 */
           SS_DISCONNECTING     /* 正在断开连接 */
       } socket_state;

      flags也是一个标志,下面是它的取值:
      #define SOCK_ASYNC_NOSPACE 0
      #define SOCK_ASYNC_WAITDATA 1
      #define SOCK_NOSPACE  2
      #define SOCK_PASSCRED  3            ops是协议相关的一系例操作的集合,包括listen, bind, connect等常用socket操作,struct proto_ops结构体在include/linux/net.h 123行。            fasync_list是一个异步唤醒的列表,结构体struct fasync_struct在include/linux/fs.h 733行            sk是一个网络层的套接字表示,关于结构体struct sock,下文会有专门介绍。      type是套接字的类型:
      enum sock_type {
           SOCK_STREAM = 1,        /*可靠字节流服务套接字,TCP*/
           SOCK_DGRAM = 2,  /*传输层数据报服务, UDP*/
           SOCK_RAW = 3,  /*网络层数据报服务, ICMP, IGMP,  原始IP*/
           SOCK_RDM = 4,  /*可靠的数据报服务*/
           SOCK_SEQPACKET = 5, /*可靠的双向记录流服务*/
           SOCK_PACKET = 10,  /*已废弃*/
      };
 
      暂时放一下struct sock,先来看看sys_socket的第一步创建struct socket中究竟做了些什么(描述越过了一些不是很重要的步骤):
      首先,检查传入的用来标识域的协议族变量family是否在合法范围内,关于family,我们只关心其中的几个值,PF_INET表示因特网协议,PF_UNIX是unix文件系统套接字。
      然后,对于(family == PF_INET && type == SOCK_PACKET )的情况,因为是已废弃的,给出警告信息。
      net_families是一个数组,所有的协议族都在这个数组中注册,数组的项是一个结构体:
      struct net_proto_family {
           int  family;
           int  (*create)(struct socket *sock, int protocol);
           short  authentication;
           short  encryption;
           short  encrypt_net;
           struct module *owner;
      };
       对于我们要创建的family,我们必须确保能在这个数组中找到相应的项(即内核支持该域)。
       在内存中创建一个struct socket,并将其type赋值为传入的type值。
       调用net_families[family]->create完成最后的创建工作。返回。
       至此,一个socket就创建成功了。但还有两个问题没有明确:struct sock结构体的内容,以及net_families[family]->create如何完成对socket的创建。下一篇将结合inet域的实际例子进行分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值