socket编程之 accept函数的理解

2024-04-12 01:32

本文主要是介绍socket编程之 accept函数的理解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在进入我们的正题之前,再来复习一波编写服务器的函数流程吧

服务器端:socket()-->bind( )-->listen()-->accept()-->read()/write()--->close()socket()//创建套接字
bind()//分配套接字地址
listen()//等待连接请求状态
accept()//允许连接
read()/write()//进行数据交换
close()//断开连接

socket()//创建套接字
bind()//分配套接字地址
listen()//等待连接请求状态

相信大家都不陌生了。所以博主就接着讲解 listen()函数的那一篇博客讲起了。其实listen() 和 accept()联系是很紧密的。

请大家要明白这一点: socket三次握手是在listen中完成,accept只从完成连接的队列中拿出一个连接
好了,那我们就来介绍 accept()函数吧。

受理客户端连接请求

      调用 listen()函数之后,若有新的连接请求,则应按序处理。受理请求意味着进入科技收数据的状态。
      也许各位已经猜到进入这种状态所需要的部件-----当然是套接字了。大家可能认为可以使用服务器端套接字,单是正如我们前面所说·,服务器端套接字是做门卫的。如果在客户端的数据交换中是用门卫,那谁来守门呢???所以我们就需要另外一个套接字了。
      那是不是意味我们要再去创建一个套接字呢??没有必要的,下面这个函数(accept())会自动创建套接字,并连接到发起请求的客户端。
      所以我们就要考虑一下是否需要自己建立一个socket套接字去接收accept返回的客户端套接字了。事实上我们就是创建了一个有关客户端的套接字用来接收返回值,从而达到与客户端进行沟通的作用。

#include<sys/socket.h>int accept(int sockfd, struct spckaddr *addr, skcklen_t *sddlen);参数:第一个参数: int sockfd:--->服务器套接字的文件描述符第二个参数: struct spckaddr *addr--->保存发起连接请求的客户端地址信息的变量地址值,也就是返回链接客户端地址信息,含IP地址和端口号需要强制转换类型,之前讲过第三个参数: skcklen_t *sddlen--->传入sizeof(addr)第二个参数的大小,函数返回时返回真正接收到地址结构体的大小值得一提的是第二个参数和第三个参数:第二个参数:传出参数,返回的连接成功的信息,所以我们不需要对这个套接字进行初始化。第三个参数:传入传出参数,一开始传入一个参数防止溢出,调用完成之后长度会发生改变。因为是类型不是int 所以我们一般会在前面定义一个 skcklen_t 变量来衡量大小。
第三个参数具体使用:
skcklen_t = cliaddr_len;
cliaddr_len = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);//因为是传入传出所以需要涉及修改值,所以传入地址。
返回值:成功:成功返回一个新的socket文件描述符,用于和客户端通信。失败:返回-1,设置errno

三方握手完成后,服务器调用accept()接受连接,如果服务器调用accept()时还没有客户端的连接请求,就阻塞等待直到有客户端连接上来

accept()函数接受连接请求等待队列中待处理的客户端连接请求。函数调用成功时,accept()内部将产生用于数据I/O的套接字,并返回器文件描述符。需要强调的是,套接字是自动创建的,并自动与发起连接请求的客户端建立连接。如图展示了 accept()函数调用的全过程。

在这里插入图片描述

如图展示了“冲等待队列中取出一个连接请求,创建套接字并完成连接请求的”过程。

书中对于这些讲的已经很详细了,所以没啥好扩充的内容所以博主就把一般的服务器结构列出来:


......skcklen_t = cliaddr_len;
while (1) {cliaddr_len = sizeof(cliaddr);connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);//connfd就是和客户端沟通的套接字。n = read(connfd, buf, MAXLINE);......close(connfd);
}

        整个是一个while死循环,每次循环处理一个客户端连接。由于cliaddr_len是传入传出参数,每次调用accept()之前应该重新赋初值。
       accept()的参数listenfd是先前的监听文件描述符,而accept()的返回值是另外一个文件描述符connfd,之后与客户端之间就通过这个connfd通讯,最后关闭connfd断开连接,而不关闭listenfd,再次回到循环开头listenfd仍然用作accept的参数。

这一篇博客基本上就要结束了,博主带大家分析一下服务器端代码吧。
在这里插入图片描述

在这里插入图片描述

(75条消息) socket编程之 accept函数的理解_dearQiHao的博客-CSDN博客

这篇关于socket编程之 accept函数的理解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/895736

相关文章

Python itertools中accumulate函数用法及使用运用详细讲解

《Pythonitertools中accumulate函数用法及使用运用详细讲解》:本文主要介绍Python的itertools库中的accumulate函数,该函数可以计算累积和或通过指定函数... 目录1.1前言:1.2定义:1.3衍生用法:1.3Leetcode的实际运用:总结 1.1前言:本文将详

轻松上手MYSQL之JSON函数实现高效数据查询与操作

《轻松上手MYSQL之JSON函数实现高效数据查询与操作》:本文主要介绍轻松上手MYSQL之JSON函数实现高效数据查询与操作的相关资料,MySQL提供了多个JSON函数,用于处理和查询JSON数... 目录一、jsON_EXTRACT 提取指定数据二、JSON_UNQUOTE 取消双引号三、JSON_KE

MySQL数据库函数之JSON_EXTRACT示例代码

《MySQL数据库函数之JSON_EXTRACT示例代码》:本文主要介绍MySQL数据库函数之JSON_EXTRACT的相关资料,JSON_EXTRACT()函数用于从JSON文档中提取值,支持对... 目录前言基本语法路径表达式示例示例 1: 提取简单值示例 2: 提取嵌套值示例 3: 提取数组中的值注意

C#多线程编程中导致死锁的常见陷阱和避免方法

《C#多线程编程中导致死锁的常见陷阱和避免方法》在C#多线程编程中,死锁(Deadlock)是一种常见的、令人头疼的错误,死锁通常发生在多个线程试图获取多个资源的锁时,导致相互等待对方释放资源,最终形... 目录引言1. 什么是死锁?死锁的典型条件:2. 导致死锁的常见原因2.1 锁的顺序问题错误示例:不同

深入理解Apache Airflow 调度器(最新推荐)

《深入理解ApacheAirflow调度器(最新推荐)》ApacheAirflow调度器是数据管道管理系统的关键组件,负责编排dag中任务的执行,通过理解调度器的角色和工作方式,正确配置调度器,并... 目录什么是Airflow 调度器?Airflow 调度器工作机制配置Airflow调度器调优及优化建议最

Java function函数式接口的使用方法与实例

《Javafunction函数式接口的使用方法与实例》:本文主要介绍Javafunction函数式接口的使用方法与实例,函数式接口如一支未完成的诗篇,用Lambda表达式作韵脚,将代码的机械美感... 目录引言-当代码遇见诗性一、函数式接口的生物学解构1.1 函数式接口的基因密码1.2 六大核心接口的形态学

PyCharm接入DeepSeek实现AI编程的操作流程

《PyCharm接入DeepSeek实现AI编程的操作流程》DeepSeek是一家专注于人工智能技术研发的公司,致力于开发高性能、低成本的AI模型,接下来,我们把DeepSeek接入到PyCharm中... 目录引言效果演示创建API key在PyCharm中下载Continue插件配置Continue引言

一文带你理解Python中import机制与importlib的妙用

《一文带你理解Python中import机制与importlib的妙用》在Python编程的世界里,import语句是开发者最常用的工具之一,它就像一把钥匙,打开了通往各种功能和库的大门,下面就跟随小... 目录一、python import机制概述1.1 import语句的基本用法1.2 模块缓存机制1.

深入理解C语言的void*

《深入理解C语言的void*》本文主要介绍了C语言的void*,包括它的任意性、编译器对void*的类型检查以及需要显式类型转换的规则,具有一定的参考价值,感兴趣的可以了解一下... 目录一、void* 的类型任意性二、编译器对 void* 的类型检查三、需要显式类型转换占用的字节四、总结一、void* 的

深入理解Redis大key的危害及解决方案

《深入理解Redis大key的危害及解决方案》本文主要介绍了深入理解Redis大key的危害及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一、背景二、什么是大key三、大key评价标准四、大key 产生的原因与场景五、大key影响与危