在前面我们理解了网络的层级结构,接下来我们要介绍socket api.
也就是下面的这些函数:
socket/bind/listen/accept/
首先这些函数都是基于内核的,也就是内核函数,内核主要用于干什么?
内核肯定是和硬件的驱动程序进行打交道的,不同的硬件放到主板上不同的位置,主板上都是电路板,大家基于主板上的电路图互相传递信号.
因为linux内核把所有的外接设备都看作文件描述符,上图中会有一块缓冲区,这块缓冲区是在内存中的,具体多大,怎么分配,动态的还是固态的,不清楚!
所以我们如果要使用网络,那么我们就需要告诉内核我们需要和硬件网卡模块进行交互了,这个时候我们首先就要创建一个socket描述符了.
使用API socket我们可以创建一个socket网络通信描述符:
socket(int domain,int type,int protocol)我们在网络中经常使用的是:socket(AF_INET,SOCK_STREAM,0);
此行代码的意思是,我们在内核创建一个网络句柄,后面的参数AF_INET,SOCK_STREAM,表示的是我们使用的是何种协议,怎么来管理数据流。
那创建的内核socket句柄怎么和硬件打交道呢?,哈哈,相信很多同学已经知道了,那就是IO操作嘛!
IO操作就涉及到阻塞和非阻塞,以及内核缓冲区大小,应用缓冲区大小等等,这些设置。
我们的Socket只是创建了一个内核通信句柄,但是很多配置还是需要进行设置的。
比如我们要和网卡打交道(其实是和网卡驱动打交道),那么大家肯定要约定一套公用的协议,比如你得告诉我,使用何种协议把,TCP/UDP? 使用哪个端口?阻塞还是非阻塞?
仅仅调用:
int sock = socket(AF_INET,SOCK_STREAM,0);
它仅仅是在内核上创建了一个网络句柄描述符.
关于上面的问题都是一些很细节的问题,因为socket细节对于我个人来说,是一种精通的层次,因此这一篇幅,只讲一些比较广泛的东西。
细节问题,我会参考linux网络编程来进行分析解决.
延伸话题:
既然我们内核可以和网卡的驱动打交道,那么很明显的,我们自己也可以和网卡驱动打交道,自己去实现TCP/IP协议,实现更高级别的定制服务.