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

相关文章

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

【C++高阶】C++类型转换全攻略:深入理解并高效应用

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C++ “ 登神长阶 ” 🤡往期回顾🤡:C++ 智能指针 🌹🌹期待您的关注 🌹🌹 ❀C++的类型转换 📒1. C语言中的类型转换📚2. C++强制类型转换⛰️static_cast🌞reinterpret_cast⭐const_cast🍁dynamic_cast 📜3. C++强制类型转换的原因📝

【编程底层思考】垃圾收集机制,GC算法,垃圾收集器类型概述

Java的垃圾收集(Garbage Collection,GC)机制是Java语言的一大特色,它负责自动管理内存的回收,释放不再使用的对象所占用的内存。以下是对Java垃圾收集机制的详细介绍: 一、垃圾收集机制概述: 对象存活判断:垃圾收集器定期检查堆内存中的对象,判断哪些对象是“垃圾”,即不再被任何引用链直接或间接引用的对象。内存回收:将判断为垃圾的对象占用的内存进行回收,以便重新使用。

C++操作符重载实例(独立函数)

C++操作符重载实例,我们把坐标值CVector的加法进行重载,计算c3=c1+c2时,也就是计算x3=x1+x2,y3=y1+y2,今天我们以独立函数的方式重载操作符+(加号),以下是C++代码: c1802.cpp源代码: D:\YcjWork\CppTour>vim c1802.cpp #include <iostream>using namespace std;/*** 以独立函数

Go Playground 在线编程环境

For all examples in this and the next chapter, we will use Go Playground. Go Playground represents a web service that can run programs written in Go. It can be opened in a web browser using the follow

深入理解RxJava:响应式编程的现代方式

在当今的软件开发世界中,异步编程和事件驱动的架构变得越来越重要。RxJava,作为响应式编程(Reactive Programming)的一个流行库,为Java和Android开发者提供了一种强大的方式来处理异步任务和事件流。本文将深入探讨RxJava的核心概念、优势以及如何在实际项目中应用它。 文章目录 💯 什么是RxJava?💯 响应式编程的优势💯 RxJava的核心概念