我们需要知道的是,Linux下一切皆文件,套接字必然和文件脱不开关系,下面就站在文件系统角度分析套接字及其接口函数在通信过程中做了哪些工作??
目录
一、服务端
1、创建套接字
使用socket函数创建套接字,其本质就是先创建一个临时文件,然后打开文件,类似于系统调用open函数,其返回值就是文件描述符fd。
这个文件描述符会和一个文件结构体struct FILE关联起来,里面包含的仅仅只是文件描述符、缓冲区等系统信息,不包含任何网络相关的信息。
2、服务端绑定IP和端口号
这里其实就是将刚刚打开的文件和 struct sockaddr_in 绑定起来(或者可以理解为将存放地址信息的结构体的地址存到这个文件结构体中)
3、将套接字设置为监听状态(调用listen函数)
这里其实是设置socket文件状态,允许其他人来连接自己。你可以理解为 “设置文件的读写权限” 。
4、accept接受连接请求
首先需要对“连接”有个感性认识。
(1) 如何理解“连接”?
我们去拜访别人之前,一般会打个电话事先说明“我是谁,我想去拜访你”,如果对方在家而且统一了,那我们就可以带上我们的礼品登门访问。
所以这里的连接其实就是在告诉对方,“我是客户端,ip地址为xxx,端口号为xxx,我想和你通信”,如果服务端在线而且允许连接的话,后面就可以带着大包小包来通信了。
(2) “连接”在OS层面的表现
“连接”在OS层面可以看作是一个结构体,里面包含了地址信息。accept函数的第三和第四个参数可以获取到对端的地址信息。
(3) 服务端如何处理多个“连接”?
多个“连接”其实就是一堆结构体,我们可以通过链表将这些“连接”管理起来。至于如何处理,可以使用多进程,也可以使用多线程或者线程池来处理。
5、接收/发送数据(send/recv)
接收就是在读取文件内容,发送就是在向文件写内容。TCP是面向字节流的传输过程,服务端可以使用read/write函数来与客户端进行通信,客户端也是如此。
6、close关闭套接字
网络层面:断开连接
系统层面:断开文件结构体和文件描述符之间的联系,释放申请的文件资源和连接资源
二、客户端
客户端我们只说明connect,因为创建套接字、绑定IP地址和端口的原理是一样的
1、connect连接服务端
本质是发起连接,这里就是上面说明accept时提到的场景,发起“连接”可以看作是打电话给朋友,告诉对方“我是谁,我想去你家”。
站在系统层面,其实就是发送一个请求报文,这里就是TCP连接的三次握手
2、close断开连接
当客户端通信结束,我们使用close断开和服务器的连接,此时服务器那边读取到的字节数为0,服务器就知道客户端断开连接了。这里就是TCP连接的四次挥手。