网络 socket epoll
 
套接字对:(源ip:源port,目的ip:目的port),唯一标识了一个网络上的TCP连接 收到报文,不仅要看目的port,还要看源ip和port才能确定报文该交给哪个连接
listen():将主动套接字转化成被动套接字,内核为每个监听套接字维护半连接队列和全连接队列
backlog参数指定半连接队列的大小,半连接队列中的项的留存时间是一个RTT
忽略超出的syn,等待客户端重传syn,而不是返回rst。
syn=1的报文段会交付给监听套接字处理
accept():从全连接队列头取一个连接,返回内核生成的描述符,全连接队列为空则阻塞。
该socket里记录了特定的4元组,
以后的tcp报文段如果匹配该4元组,就直接交给这个socket处理
write():内核从应用程序缓冲区复制数据到TCP缓冲区,TCP缓冲区可能装不下全部数据,
write()将一直阻塞,直到所有数据都到达TCP缓冲区,才返回成功。 此时数据并未到达对方节点,只是应用程序缓冲区可以使用了。 TCP会负责将TCP缓冲区的数据发送到目的节点的接收缓冲区。
read():应用程序通过套接字,读取接收缓冲区的数据。
close():默认是把套接字标记成关闭,然后立即返回应用程序,此后该套接字不能被read()或write()
然后TCP将尝试发送排队的数据,然后发送中止序列
引用计数:每个文件或套接字都有一个引用计数,
它是当前打开着的,引用了该文件或套接字的描述符个数
父进程打开一个套接字,该套接字的引用计数为1
父进程fork()之后,该套接字的引用计数为2
select()
每次select(),都要将大量的描述符从用户态复制到内核态
内核要多次遍历全部描述符,才能知道有没有就绪fd,
每遍历32/64个,还要让出控制权,等待下次被调度后才能继续向后遍历
select返回全部fd,应用程序要再遍历一遍才能知道哪些是就绪的
描述符有最大数量限制,32位机默认1024,64位机默认2048
epoll 源码分析
callback函数,不需要遍历
红黑树,高效
没有数量限制
存疑:mmap,不需要用户态和内核态间的复制
 
网卡将分组存入内存中,发中断,让cpu执行驱动程序。
接收:驱动程序重置硬件中断、让网卡继续接收分组、将ip分组放到队列中,通知ip进程有分组到达
ip将报文段放到某处,tcp从某处读取报文段,并找到报文段所属的连接,将报文段中的数据放到该连接的缓冲区内,并向发送方发送ack,如果报文段中含有ack,tcp还要处理定时器。
发送:ip进程将分组放到队列中,调用驱动程序启动硬件,输出完成后,硬件向cpu发送中断,驱动程序将队列中的数据删除。队列中如果还有数据就继续发送。
 
                    
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号