listen监听队列刨析

listen函数:
在这里插入图片描述
对于listen函数来说,它使用来监听端口的,它用在TCP网络通信当中的服务器角色,UDP和客户端都是不需要它的。当我们在编写网络通信程序时,调用socket函数创建了一个套接字以后,改套接字就对应的和相应的输出缓冲区和输入缓冲区建立了联系,此时改套接字的状态正处于CLOSED(观察TCP状态转换图即可),当我们调用listen函数以后,改套接字的状态就变成了LISTEN监听状态,此时,处于等待客户端连入的状态。

这里的话,主要记录一下listen的第二个参数的意思吧。

对于一个调用listen进行监听的套接字’操作系统会为其维护2个队列:未完成连接队列和已完成连接队列。
(1)未完成连接队列中的连接
当客户端发送TCP连接三次握手的第1次(即SYN包)时,服务器端会在未完成连接队列中创建一个与该SYN包对应的项,可以把该项看成一个半连接(因为连接尚未建立)该半连接的状态会从LISTEN变成SYNRCVD同时向客户端返回第2次握手的包
(SYN’ACK)而此时服务器正在等待完成第3次握手
2)已完成连接队列中的连接
3次握手完成后’该连接就变成ESTABLISHED状态’每个已经完成3次握手的客户端连接(完整说法应该是“服务器端的与客户端对应的socket连接”)都放在这个队列中作为一项。

如下所示:
在这里插入图片描述
在这里插入图片描述
从上图可以看到客户端发送的三次握手的第1个SYN包从图的下方发送过’在三次握手完成之前’连接都会在未完成连接队列中;三次握手完成后’该连接就从未完成连接队列转移到已完成连接队列。

而listen函数”曾经“的含义为这两个队列的和不超过backlog,实际上由于操作系统的原因可能会比这个值稍微多一些。
在这里插入图片描述
而现在由于考虑到syn攻击,backlog参数的含义改为了已连接队列之和,去除了半连接队列之和了。

举一个例子,在socket编程当中,如果我们在服务端不用accept函数,,listen函数的第二个参数设置为5,那么这个时候,可以成功连接的客户端就是最多可以成功连入5个,每连入一个,队列的项数就会加一(减一的话就是用accept函数去取出来),所以当项数达到5时,客户端自然就会连不上了。

可以通过以下方式查看连接队列的大小。
在这里插入图片描述
对于,全连接队列已满的情况,如果客户端再次发起请求,服务端有两种处理手段,
在这里插入图片描述
我们也可以通过以下方式查看是否有队列溢出的情况。
在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在Spring Boot中使用Redis队列监听可以实现异步消息处理和任务调度。下面是一个简单的示例: 1. 首先,确保你的Spring Boot项目中已经添加了Redis和Spring Data Redis的依赖。 2. 创建一个消息监听器类,用于处理接收到的消息。可以使用`@Component`注解将其声明为一个Spring组件。 ```java @Component public class MessageListener { @Autowired private RedisTemplate<String, String> redisTemplate; @Autowired private TaskExecutor taskExecutor; @Autowired private MessageService messageService; @PostConstruct public void init() { taskExecutor.execute(this::listen); } public void listen() { while (true) { String message = redisTemplate.opsForList().rightPop("messageQueue", 1, TimeUnit.SECONDS); if (message != null) { // 处理接收到的消息 messageService.processMessage(message); } } } } ``` 在上面的代码中,我们使用`RedisTemplate`来操作Redis,通过`rightPop`方法从名为"messageQueue"的列表中获取消息。如果获取到了消息,则调用`messageService`来处理消息。 3. 创建一个消息处理服务类,用于实际处理接收到的消息。 ```java @Service public class MessageService { public void processMessage(String message) { // 处理接收到的消息逻辑 System.out.println("Received message: " + message); } } ``` 在上面的代码中,我们只是简单地打印接收到的消息,你可以根据实际需求进行相应的处理。 4. 在需要发送消息的地方,使用`RedisTemplate`将消息发送到队列中。 ```java @Autowired private RedisTemplate<String, String> redisTemplate; public void sendMessage(String message) { redisTemplate.opsForList().leftPush("messageQueue", message); } ``` 在上面的代码中,我们使用`leftPush`方法将消息推送到名为"messageQueue"的列表的左侧。 这样,当有消息被推送到队列中时,监听器会自动从队列中获取消息并进行处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值