在网络通信中,收发信息的双方可以通过调用特定的方法来中断通信连接。
close 、shutdown 这两个函数便是用于实现这个功能的。
那么所谓的中断通信是以何种方式进行的?计算机中又是通过何种命令“中断"通信双方收发消息呢?
我们可以这么想,把client端和server端分别想象成通信的两个人C君和S君,那么client端向server端
发送请求便是C向S写信,C将写好的信放入到C所在地的邮箱中,信会被邮递员从C的邮箱中投递到S所在地的S的邮箱中。
若是S向C回复信息,便是将写好的信投入S所在地的邮箱中,信会被邮递员从S的邮箱中投递到C所在地的邮箱中。
若是 C 首先发起中断关闭二者的连接的话,C 会将它所在地的邮箱移走,所以S再有发送给 C的信息
C 便再也不会理会。 若是 S 首先发起关闭二者的连接的话,S 也会效仿 C 将自己所在地的接收信息的的邮箱移除。
没错,回到 client 和server端,这个邮箱便是用来存放将要<发送给对方的消息数据>或是<接收来自对方消息数据>的缓冲区,
如果看过前面文章的话,就会知道这个缓冲区是由套接字描述符来描述的,那么如果想要中断连接的话,就是释放缓冲区(移出自己的邮箱)
那么如何释放缓冲区呢? 可以这么想,套接字描述符等同于文件描述符,带到文件中的数据全部写入到磁盘终止后,释放/关闭一个文件,
便是 close (fd/ 文件描述符值) ; 那么释放这块缓冲区也是同样的方法 close (sock_fd/ 套接字描述符) ;
这便是为何关闭连接是使用 close (套接字描述符的方法了) ; 这里应该清楚的是所谓的主动关闭连接的一方
并非是向对端发送消息告知其不要在发送数据,而是主动的关闭自己用来收发消息数据的缓冲区,
这样自己便不会发送和接收任何来自于网络的消息了。而对方在发送消息之后没有接到任何的回复消息,
会经历超时、重传一顿折腾之后而认为对等通信端关闭了通信,便不再向其发送数据,
然后根据实际情况将自己本地专门用来缓存与对等通信端收发信息的空间释放。
所以,上面的问题,中断通信是以何种方式进行的? 是以释放掉本地收发数据的缓冲区来进行的
计算机中又是通过何种命令“中断"通信双方收发消息呢? 是通过关闭连接的套接字描述符来实现的
close 函数 API 描述
#include // unix standard library
int close ( int fd ) ;
参数
fd : 通信双方在建立连接之后的 套接字描述符,若是 server 端便是 accept 函数调用的返回值 若是 client 端便是 connect 函数调用成功返回后的,socket 函数返回值
返回值:
成功关闭连接(释放缓冲空间)返回 0 , 失败返回-1
shutdown API 描述
#include
int shutdown ( int s , int how ) ;
参数 :
1. s : 这个参数的作用于 close 函数中的 fd 相同,是套接字描述符
2. how : 这个参数类似于控制命令,对应了一个通过宏来描述的指令集{SHUT_RD,SHUT_WR,SHUT_RDWR}
该指令集是用来描述以何种方式来关闭连接的
返回值:
成功执行对应方式的关闭套接字,返回0 , 关闭失败,返回 -1
shutdown 功能要多余 close ,shutdown 可以将一个通信端置为半关闭的状态(只接收数据但是不能发送,
只能发送数据但是不能接收)
在这里介绍一下shutdown 函数中的不同关闭方式
1. SHUT_RD : 将当前的通信端置为半关闭状态,是只能发送数据(write)但是不能接受数据(read)
发送数据所指的是当前通信端点仅能将将要发送的数据从进程内存中写入到内核缓冲区中,
系统可以将内核缓冲区中的数据进行打包发送到网络的另一端,此时该缓冲区仅仅能够接收
来自进程内存中的数据,而无法接收并缓存来自对端发送过来的数据。
2. SHUT_WR : 将当前的通信端置为半关闭状态,是只能接收数据(将来源于网络存放到内核缓冲区中数据
读入到进程内存中) ,但是不能发送数据(进程内存中的数据无法写入到内核缓冲区并发送到网络对端)
3. SHUT_RDWR: 若是将参数置为 SHUT_RDWR 功能上便于 close 函数相同, 它的意思便是禁止内核缓冲区与进程内存
中的数据进行交换。读写通道全部被关闭, 但是该套接字描述符对应的空间是释放还是禁用尚不确定
示例代码 略
阅读(1334) | 评论(0) | 转发(0) |