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

相关文章

MySQL常用字符串函数示例和场景介绍

《MySQL常用字符串函数示例和场景介绍》MySQL提供了丰富的字符串函数帮助我们高效地对字符串进行处理、转换和分析,本文我将全面且深入地介绍MySQL常用的字符串函数,并结合具体示例和场景,帮你熟练... 目录一、字符串函数概述1.1 字符串函数的作用1.2 字符串函数分类二、字符串长度与统计函数2.1

python使用try函数详解

《python使用try函数详解》Pythontry语句用于异常处理,支持捕获特定/多种异常、else/final子句确保资源释放,结合with语句自动清理,可自定义异常及嵌套结构,灵活应对错误场景... 目录try 函数的基本语法捕获特定异常捕获多个异常使用 else 子句使用 finally 子句捕获所

Java Spring的依赖注入理解及@Autowired用法示例详解

《JavaSpring的依赖注入理解及@Autowired用法示例详解》文章介绍了Spring依赖注入(DI)的概念、三种实现方式(构造器、Setter、字段注入),区分了@Autowired(注入... 目录一、什么是依赖注入(DI)?1. 定义2. 举个例子二、依赖注入的几种方式1. 构造器注入(Con

postgresql使用UUID函数的方法

《postgresql使用UUID函数的方法》本文给大家介绍postgresql使用UUID函数的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录PostgreSQL有两种生成uuid的方法。可以先通过sql查看是否已安装扩展函数,和可以安装的扩展函数

MySQL字符串常用函数详解

《MySQL字符串常用函数详解》本文给大家介绍MySQL字符串常用函数,本文结合实例代码给大家介绍的非常详细,对大家学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql字符串常用函数一、获取二、大小写转换三、拼接四、截取五、比较、反转、替换六、去空白、填充MySQL字符串常用函数一、

C++中assign函数的使用

《C++中assign函数的使用》在C++标准模板库中,std::list等容器都提供了assign成员函数,它比操作符更灵活,支持多种初始化方式,下面就来介绍一下assign的用法,具有一定的参考价... 目录​1.assign的基本功能​​语法​2. 具体用法示例​​​(1) 填充n个相同值​​(2)

MySql基本查询之表的增删查改+聚合函数案例详解

《MySql基本查询之表的增删查改+聚合函数案例详解》本文详解SQL的CURD操作INSERT用于数据插入(单行/多行及冲突处理),SELECT实现数据检索(列选择、条件过滤、排序分页),UPDATE... 目录一、Create1.1 单行数据 + 全列插入1.2 多行数据 + 指定列插入1.3 插入否则更

PostgreSQL中rank()窗口函数实用指南与示例

《PostgreSQL中rank()窗口函数实用指南与示例》在数据分析和数据库管理中,经常需要对数据进行排名操作,PostgreSQL提供了强大的窗口函数rank(),可以方便地对结果集中的行进行排名... 目录一、rank()函数简介二、基础示例:部门内员工薪资排名示例数据排名查询三、高级应用示例1. 每

全面掌握 SQL 中的 DATEDIFF函数及用法最佳实践

《全面掌握SQL中的DATEDIFF函数及用法最佳实践》本文解析DATEDIFF在不同数据库中的差异,强调其边界计算原理,探讨应用场景及陷阱,推荐根据需求选择TIMESTAMPDIFF或inte... 目录1. 核心概念:DATEDIFF 究竟在计算什么?2. 主流数据库中的 DATEDIFF 实现2.1

深入理解Go语言中二维切片的使用

《深入理解Go语言中二维切片的使用》本文深入讲解了Go语言中二维切片的概念与应用,用于表示矩阵、表格等二维数据结构,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录引言二维切片的基本概念定义创建二维切片二维切片的操作访问元素修改元素遍历二维切片二维切片的动态调整追加行动态