网络编程api总结

1、socket函数创建一个socket连接,此时该socket连接为主动式。 fd(int)->fd(struct fd)->file->sock;sock->file 

2、bind函数把socket与ip和端口绑定,并且把socket连接从 主动式 改为 被动式,成为服务端,只能够接受客户端的连接,不能发起连接。

3、listen函数开始监听socket,开始接受客户端的连接,不会阻塞(或者只会因为锁阻塞);backlog参数:建立连接的全连接队列大小限制;未完成三次握手的半连接队列有另外的参数限制

4、accpet函数从全连接队列取出 new sd,,然后开始工作。默认可阻塞(浅度睡眠),可以在sd创建后设置 不阻塞 属性;https://blog.csdn.net/tanyjin/article/details/69403220

5、connet函数发起三次握手建立连接,在三次握手期间也分为阻塞和非阻塞两种。

ipv4源码参考:

 1 static int inet_csk_wait_for_connect(struct sock *sk, long timeo)
 2 {
 3     struct inet_connection_sock *icsk = inet_csk(sk);
 4     DEFINE_WAIT(wait);
 5     int err;
 6 
 7     /*
 8      * True wake-one mechanism for incoming connections: only
 9      * one process gets woken up, not the 'whole herd'.
10      * Since we do not 'race & poll' for established sockets
11      * anymore, the common case will execute the loop only once.
12      *
13      * Subtle issue: "add_wait_queue_exclusive()" will be added
14      * after any current non-exclusive waiters, and we know that
15      * it will always _stay_ after any new non-exclusive waiters
16      * because all non-exclusive waiters are added at the
17      * beginning of the wait-queue. As such, it's ok to "drop"
18      * our exclusiveness temporarily when we get woken up without
19      * having to remove and re-insert us on the wait queue.
20      */
21     for (;;) {
22         prepare_to_wait_exclusive(sk_sleep(sk), &wait,
23                       TASK_INTERRUPTIBLE);
24         release_sock(sk);
25         if (reqsk_queue_empty(&icsk->icsk_accept_queue))
26             timeo = schedule_timeout(timeo);
27         sched_annotate_sleep();
28         lock_sock(sk);
29         err = 0;
30         if (!reqsk_queue_empty(&icsk->icsk_accept_queue))
31             break;
32         err = -EINVAL;
33         if (sk->sk_state != TCP_LISTEN)
34             break;
35         err = sock_intr_errno(timeo);
36         if (signal_pending(current))
37             break;
38         err = -EAGAIN;
39         if (!timeo)
40             break;
41     }
42     finish_wait(sk_sleep(sk), &wait);
43     return err;
44 }

5、connet函数从

源码参考:

ipv4代码路径:linux/net/ipv4/af_inet.c

初始化代码:

1 static int __init inet_init(void)
2      ---proto_register(&tcp_prot, 1);
3      ---inet_register_protosw(q);

关键数据结构的值,sd的操作全部在里面:

 1 static struct inet_protosw inetsw_array[] =
 2 {
 3     {
 4         .type =       SOCK_STREAM,
 5         .protocol =   IPPROTO_TCP,
 6         .prot =       &tcp_prot,
 7         .ops =        &inet_stream_ops,
 8         .flags =      INET_PROTOSW_PERMANENT |
 9                   INET_PROTOSW_ICSK,
10     },
11 
12     {
13         .type =       SOCK_DGRAM,
14         .protocol =   IPPROTO_UDP,
15         .prot =       &udp_prot,
16         .ops =        &inet_dgram_ops,
17         .flags =      INET_PROTOSW_PERMANENT,
18        },
19 
20        {
21         .type =       SOCK_DGRAM,
22         .protocol =   IPPROTO_ICMP,
23         .prot =       &ping_prot,
24         .ops =        &inet_sockraw_ops,
25         .flags =      INET_PROTOSW_REUSE,
26        },
27 
28        {
29            .type =       SOCK_RAW,
30            .protocol =   IPPROTO_IP,    /* wild card */
31            .prot =       &raw_prot,
32            .ops =        &inet_sockraw_ops,
33            .flags =      INET_PROTOSW_REUSE,
34        }
35 };
原文地址:https://www.cnblogs.com/shihuvini/p/9363515.html