listen()函数
在进入我们的函数讲解前大家再回顾一下编写服务器端的流程
服务器端: socket()-->bind( )-->listen()-->accept()-->read()/write()--->close() socket()//创建套接字 bind()//分配套接字地址 listen()//等待连接请求状态 accept()//允许连接 read()/write()//进行数据交换 close()//断开连接
相信大家对 socket()和 bind()应该不陌生了,那我们就再接再厉把 listen() 也拿下吧。
下面博主给出具体的函数
#include<sys/socket.h> int listen(int sock, int backlog); 参数含义: 第一个参数: int sock: 希望进入等待连接请求状态的套接字文件描述符,传递的描述符套接字参数成为服务器端套接字(监听套接字!!!!) 第二个参数: int backlog: 连接请求等待队列的长度,若为5,则队列长度为5,表示最多使5个连接请求进入队列,其中也包含排队建立3次握手队列和刚刚建立3次握手队列的连接数之和 返回值: 成功: 0 失败: -1
典型的服务器程序可以同时服务于多个客户端,当有客户端发起连接时,服务器调用的accept()返回并接受这个连接,如果有大量的客户端发起连接而服务器来不及处理,尚未accept的客户端就处于连接等待状态,listen()声明sockfd处于监听状态,并且最多允许有backlog个客户端处于连接待状态,如果接收到更多的连接请求就忽略。
博主认为下面这两张图对我们的两个参数解释得非常形象,就分享给大家看了。
查看系统默认backlog
cat /proc/sys/net/ipv4/tcp_max_syn_backlog
如何设置操作系统中backlog的值??
按照下面的步骤操作即可:
vim /etc/sysctl.conf
最后添加
net.core.somaxconn = 1024
net.ipv4.tcp_max_syn_backlog = 1024
保存,然后执行,就能更改系统默认的backlog
为什么要去更改backlog呢??
因为 listen()第二个参数表面上是让你自己设置,但是一旦你设置的数字超过了系统默认的 backlog那么系统就会选择默认的 backlog 你设置的参数就不起作用了。
三次握手
下面就有博主给大家分享一些比较专业的知识了(博主也许讲的不是很好,但是博主会尽自己最大努力去讲好的)------>介绍的是 TCP 首先让我们看下下面的图(重点注意红色的箭头)
下面这张图就包含了三次握手和四次挥手(在后面的内容会介绍到的
1.首先客户端(client)发一个SYN 1000(0字节)请求给客户端,希望与服务器建利连接
2.服务器端(server)接收到之后返回ACK(接受客户端发来的字节数 1000+1),在发送SYN 8000(0)字节同时也希望和客户端建立连接。
3.客户端接收到服务器端的ACK回应之后再返回ACK(服务器端发来的SYN 8000+1)给服务器端,这样客户端和服务器端就建立了连接。
这就是三次握手,通俗的来说就是:
-
套接字A:"你好,套接字B。我这里有数据要传递给你,我们建立连接吧"
-
套接字B:“好的,我这边已就绪”
-
套接字A:“谢谢你受理我的请求”
书上的图:(更容易理解): ![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/20191031203439767.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2RlYXJRaUhhbw==,size_16,color_FFFFFF,t_70)
如果其中的数据不一样就会发生下面的情况(给出书上),这也就是为什么说 TCP是面向连接的、可靠的、数据完整的基于字节流的连接的原因了。
其中的原理就是 SYN与ACK做的。