趣谈网络协议(十三):Socket套接字

Socket简介

    咱们都知道,使用TCP协议进行包传输的过程都须要使用三次握手创建链接,交互完又得四次挥手断开链接.对于一个交互频繁的两端来讲,若是每次发送包都得三次握手、四次挥手这无疑大大下降了发送的效率。node

    Socket就很好的解决了上述的问题,它是基于传输层TCP、UDP协议的Socket编程。socket编程进行的是端到端的传输,中间通过多少个局域网、路由都不关它的事。所以咱们能设置的参数只要传输和网络层linux

    使用Socket时须要设置的参数.如使用的是ipv4仍是ipv6协议,用的是TCP仍是UDP,若是用的是TCP协议,则类型为SOCK_Stream,上节讲过传输层使用TCP协议时使用流发送到网络IP层,IP层加上本身的头变成一个包发送给上一层(MAC层)。UDP的类型是包的方式,为SOCK_DGRAM编程

基于TCP协议的Socket程序函数调用过程

    TCP服务端要先监听一个端口,通常是先调用bind函数,给这个Socket赋予IP和端口。再调用listen函数让其处于监听状态数组

    在内核中.为每一个Socket维护两个队列,一个是已经完成三次握手创建链接的队列,处于establish状态。另外一个是还没彻底创建链接正在三次握手中的,处于syn_rcvd。缓存

接下来,服务端调用accept函数获取完成的链接进行处理(若是还没完成链接则继续等待)网络

    客户端调用connect发起链接指明目标IP和端口.而后开始三次握手,内核会给客户端分配一个临时的端口。一旦握手成功,服务端的accept就会返回另外一个Socket。在这里监听的Socket和真正用来传输数据的Socket是两个,一个叫监听Socket一个叫作已链接Socket数据结构

    链接创建成功后,双方就能够进行read、write以下图socket

    

内核中的Socket

    说TCP的Socket是一个文件流,确实是这么一回事。函数

在linux内核中,Socket就是一个文件,那对应的也就有文件描述符(若是对文件及文件描述符这一律念不够熟悉的,建议先入门操做系统原理或者百度一下先)。socket的read、write都是经过文件描述符来进行。spa

每一个进程都有一个数据结构task_struct,里面指向一个文件描述符数组,来列出这个进程打开的全部文件的文件描述符。文件描述符是一个整数,是这个数组的下标。

这个数组中的内容是一个指针,指向内核中全部打开文件的列表。既然是一个文件,就会有一个inode,只不过socket对应的inode不像真正的文件系统同样,保存在硬盘上的,而是在内存中。在这个inode中,指向了socket在内核中的socket结构。

在这个结构里面,主要的是两个队列,一个是发送队列,一个是接收队列。在这两个队列里面保存的是一个缓存的sk_buff.这个缓存里面可以看到完整的包结构。

上图就是数据结构示意图.名词解释-strcut:结构体,inode:索引节点

基于UDP协议的Socke程序函数调用过程

    UDP相对简单一些,他没有像TCP那样复杂的握手挥手。但UDP一样须要Ip和端口,因此一样须要调用bind函数。

UDP是没有维护链接状态的,于是不须要每对链接创建一组socket,而是只要有一个socket,就可以和多个客户端通讯。也正是由于没有链接状态,每次通讯的时候,都调用sendto和recvfrm,均可以传入IP地址和端口。以下图

相关文章
相关标签/搜索