【Linux网络编程】TCP套接字

TCP与UDP的区别:

        udp是无连接的、面向数据报(通信时以数据报为单位传输)的传输层通信协议,其中每个数据报都是独立的,通信之前不需要建立连接,bind绑定套接字后直接可以进行通信。

        tcp是面向连接的、基于字节流(通信时以字节为单位传输)的传输层通信协议,所以通信之前必须先建立连接。其中服务器是被连接的,需要等待客户端的连接。

        这里着重说明下,TCP的面向字节流意味着在发送和接收数据时是以字节为单位进行的。TCP协议在传输数据时,将数据视为连续的字节流。这意味着,虽然应用程序和TCP的交互可能是一次一个数据块(大小不等),但TCP在传输层会将这些数据块看作是一连串的字节,并依次进行传输。接收端在收到这些字节后,会按照发送端的顺序重新组合成原始数据。UDP是以数据报为单位进行的,将信息分割成独立的信息或报文。具体原理后面文章会详细说明。

TCP中的发送和接收函数:

        注意:在TCP套接字通信中,接收和发送数据时不能使用recvfrom和sendto函数。TCP是面向字节流的,UDP是面向数据报的,recvfrom和sendto两函数是依赖于数据包的来源地址和端口进行通信,读取和发送都是一个一个数据报的形式,是专门为UDP协议规则设计的,而TCP通信时是通过已经建立的连接进行且是字节流的形式,不需要指定目标地址和端口。因此,在设计网络应用程序时,需要根据所使用的协议(TCP或UDP)选择合适的函数。

        TCP通信时通常使用write(发送数据)和read(接收数据)或者send(发送数据)和recv(接收数据)。这两套函数都是面向字节流发送和接收数据的,用法与sendto和recvfrom用法类似,这里不做说明,具体的使用后面会做代码演示。

TCP套接字必备的函数接口:

        1,listen。该函数用于将套接字设置为监听状态,这是一种被动模式,即将其标记为用于接受客户端连接请求的套接字,以接受来自客户端的连接请求。这个函数通常在服务器程序中调用,通常是在服务器进程正在准备好接受来自客户端的连接,并在调用 bind 函数时将套接字与特定地址(IP地址和端口号)关联之后使用。

        当listen函数被调用时,它告诉内核这个套接字现在处于被动模式,并准备接受客户端的连接请求。内核会在自己的进程空间里维护一个队列来跟踪这些连接请求。当客户端尝试连接到服务器时,它们的连接请求会被放入这个队列中。服务器进程可以调用accept函数来从这个等待队列中取出连接请求并建立新的连接。

头文件:

        #include <sys/types.h>
        #include <sys/socket.h>

格式:

        int listen(int sockfd, int backlog);

参数说明:

  • sockfd:要监听套接字的文件描述符。
  • backlog:指定系统内核应为相应套接字排队的最大连接数,即最多有多少个客户端可以同时处于连接等待状态。如果接收到更多的连接请求,这些请求将被忽略。它通常是一个较小的整数,如2到4,也可以设置为系统定义的最大值:SOMAXCONN。

返回值:

        成功时,返回0;失败时,返回-1。

        2,accept。该函数是在实现基于 TCP/IP 协议的服务器端程序时,用于从监听套接字上接受一个连接请求(从等待队列中取出一个已完成的连接),并创建一个新的套接字,该套接字将用于与客户端进行通信。此函数通常在调用 listen 函数之后使用,listen 函数会使服务器套接字进入监听状态,等待客户端的连接请求。

头文件:

        #include <sys/types.h>

        #include <sys/socket.h>

格式:

        int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

参数说明:

  • sockfd:一个监听套接字的描述符,该套接字是通过 listen 函数设置为监听状态的套接字。
  • addr:指向 sockaddr 结构体的指针,该结构体用于存储接受连接的地址信息。如果不需要这些信息,可以将其设置为 NULL
  • addrlen:指向包含 addr 结构体大小的变量的指针。函数返回时,它会被更新为实际存储在 addr 地址中的实际大小。如果 addr 是 NULL,则 addrlen 也为 NULL

返回值:

        成功时,返回一个非负值,这个值是一个新的套接字描述符,用于与接收到的客户端连接进行通信。

        失败时,返回 -1。

        注意:accept返回的套接字与listen监听的套接字在TCP/IP网络通信中扮演着不同的角色。listen监听的套接字是用于服务端进入监听状态,等待来自客户端的连接请求。它不会直接用于数据的发送和接收,而是作为接受连接请求的入口。 该套接字在服务器的整个生命周期中只被创建一次且只有一个(对于每个监听的端口)。accept返回的套接字是用于与客户端进行实际的通信,即数据的发送和接收。当服务器监听到客户端的连接请求后,服务器会通过accept函数从监听套接字的等待队列中取出一个连接请求,并创建一个新的套接字(即已连接套接字,用于与客户端通信)。该套接字只存在于服务器为一个客户端服务的过程中。一旦与客户端的连接关闭,该套接字就会被销毁。

        3,connect。该函数用于TCP客户端与TCP服务器建立连接。当调用此函数时,TCP客户端会发起三次握手操作(具体细节后面理论文章说明),尝试与服务器建立连接。

头文件:

        #include <sys/types.h>

        #include <sys/socket.h>

格式:

        int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数说明:

  • sockfd:由socket函数返回的套接字描述符,代表客户端的套接字。
  • addr:一个指向包含服务器IP地址和端口号的地址结构的指针。
  • addrlenaddr地址的大小。

返回值:

        如果连接成功,函数返回0;如果连接失败,函数返回-1。

TCP服务端的连接处理:

        由于TCP通信是建立在客户端连接上进行的,而这里的连接服务器如同 “排队买饭,一次一人” 道理,所以,TCP通信的服务端一次只能处理一个客户端的连接请求,其它客户端的连接请求需要被服务器等待处理,直到当前连接的客户端断开为止其它客户端才能连接,即多个客户端不会同时绑定一个服务器连接。为了实现多个客户端与服务器的同时通信,服务器通常需要使用多线程、多进程(不推荐)、进程池(不推荐)、线程池或异步处理机制(这里可理解为一个执行流不能在相同时间内绑定多个连接)等。这样,服务器可以同时处理多个客户端的请求,而不会造成阻塞或延迟。

close关闭套接字:

        close函数用于关闭套接字且释放其资源。

        对于TCP套接字,close函数的调用是非常重要的。在TCP中,套接字的建立与连接是一个有序的过程,保证其可靠性,如果不关闭TCP套接字,可能会导致资源泄漏(如文件描述符、内存等),并且服务器可能会认为客户端仍然连接着,从而保持不必要的状态信息。

        对于UDP套接字,情况有所不同。由于UDP是无连接的协议,每个数据报都是独立的,并且不保证顺序或可靠性,因此没有像TCP那样的连接状态需要维护。这意味着UDP套接字不需要像TCP套接字那样经历一个有序的关闭过程。但是,调用close函数仍然是一个好习惯,因为它会释放由套接字占用的系统资源。这些资源包括文件描述符、内存缓冲区等。如果不关闭UDP套接字,这些资源将不会被释放,将会导致资源泄露。

TCP套接字代码示例:

        TCP套接字这里设计了单进程单线程、多进程、多线程版本,相关代码请在此链接下观看:TCP套接字的代码实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/62573.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

spring-boot-maven-plugin 标红

情况&#xff1a;创建好 Spring Boot 项目后&#xff0c;pom.xml 文件中 spring-boot-maven-plugin 标红。 解决方案&#xff1a;加上 Spring Boot 的版本即可解决。

xv6前置知识

fork函数 一个进程,包括代码、数据和分配给进程的资源。fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。 一个进程调用fork()函数后,系统先给新的进程分…

(11)(2.2) BLHeli32 and BLHeli_S ESCs(二)

文章目录 前言 1 传递支持 前言 BLHeli 固件和配置应用程序的开发是为了允许配置 ESC 并提供额外功能。带有此固件的 ESC 允许配置定时、电机方向、LED、电机驱动频率等。在尝试使用 BLHeli 之前&#xff0c;请按照 DShot 设置说明进行操作(DShot setup instructions)。 1 传…

Flink的双流join理解

如何保证Flink双流Join准确性和及时性、除了窗口join还存在哪些实现方式、究竟如何回答才能完全打动面试官呢。。你将在文中找到答案。 1 引子 1.1 数据库SQL中的JOIN 我们先来看看数据库SQL中的JOIN操作。如下所示的订单查询SQL&#xff0c;通过将订单表的id和订单详情表ord…

1.1 数据结构的基本概念

1.1.1 基本概念和术语 一、数据、数据对象、数据元素和数据项的概念和关系 数据&#xff1a;是客观事物的符号表示&#xff0c;是所有能输入到计算机中并被计算机程序处理的符号的总称。 数据是计算机程序加工的原料。 数据对象&#xff1a;是具有相同性质的数据元素的集合&…

【程序人生】“阶段总结“-前路茫茫

岁月如白驹过隙&#xff0c;如指尖流沙&#xff0c;不知不觉已经离开了陪伴我度过四年岁月的学校&#xff0c;离开了那间堆满各种书籍的宿舍&#xff0c;离开了通宵开发的实验室&#xff0c;离开了教室里的最后一排课桌椅......&#xff08;虽然&#xff0c;我并不是很喜欢它&a…

Android 13 编译Android Studio版本的Launcher3

Android 13 Aosp源码 源码版本Android Studio版本Launcher3QuickStepLib (主要代码) Launcher3ResLib(主要资源)Launcher3IconLoaderLib(图

数据库学习记录02

DQL【数据查询语言】 1.基础查询 1.1语法 select * | {[DISTINCT] column | expression[alias], ...} from table; 特点 查询列表可以是表中的字段、常量值、表达式、函数。 查询的结果是一个虚拟的表格。 #1.查询表中的单个字段 select name from employees;#2.查询表中…

采用片上光学相控阵的激光雷达

激光雷达基础知识 LIDAR 基于众所周知的 RADAR 原理雷达是20世纪初就存在的著名技术激光雷达使用光频率而不是无线电波 激光雷达和雷达 使用相控阵的激光雷达通过干涉来提高方向性 激光雷达的输出剖面是阵列因子和单天线远场的乘积。 N &#xff1a;天线数量 k &#xff1a;…

【通信协议】CAN总线通信协议的学习,(三)stm32f103系列单片机,can通信的代码实现

目录 1、CAN 的基本知识 2、CAN的cubemx配置 3、CAN的代码实现 3.0、初始化&#xff0c;认识函数及变量 3.1、CAN发送 3.1.1、代码1 3.1.2、代码2 3.1.3、代码3 3.2、CAN中断接收 3.2.1、代码1 3.2.2、代码2 3.2.3、代码3 3.3、过滤器 3.3.1、代码1 3.3.2、代码…

「Mac畅玩鸿蒙与硬件33」UI互动应用篇10 - 数字猜谜游戏

本篇将带你实现一个简单的数字猜谜游戏。用户输入一个数字&#xff0c;应用会判断是否接近目标数字&#xff0c;并提供提示“高一点”或“低一点”&#xff0c;直到用户猜中目标数字。这个小游戏结合状态管理和用户交互&#xff0c;是一个入门级的互动应用示例。 关键词 UI互…

不同类型转换

如果赋值运算两侧是数值型或字符型&#xff0c;但类型不一致时&#xff0c;赋值时自动进行类型的转换。 赋值转换规则&#xff1a;使赋值号右边表达式值自动转换成其左边变量的类型 350为int型&#xff0c;占4个字节&#xff0c;char占一个字节 350二进制&#xff1a; 000000…

计算机毕业设计Python+LSTM天气预测系统 AI大模型问答 vue.js 可视化大屏 机器学习 深度学习 Hadoop Spark

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

操作系统 | 学习笔记 | 王道 | 2.4死锁

2.4 死锁 文章目录 2.4 死锁2.4.1 死锁的概念2.4.2 死锁预防2.4.3 死锁避免2.4.4 死锁检测和解除 2.4.1 死锁的概念 死锁的定义 在并发环境下&#xff0c;各进程因竞争资源而造成的一种互相等待对方手里的资源&#xff0c;导致各进程都阻塞&#xff0c;都无法向前推进的现象&am…

路径规划之启发式算法之二:遗传算法(Genetic Algorithm)

遗传算法&#xff08;Genetic Algorithm, GA&#xff09;是一种基于自然选择和遗传学原理的优化搜索算法&#xff0c;它通过模拟自然界的进化过程来寻找最优解。 一、基本原理 遗传算法的基本原理是模拟自然选择、遗传和突变等生物进化过程。它通过将问题的求解过程转换成类似…

软件质量保证——单元测试之白盒技术

笔记内容及图片整理自XJTUSE “软件质量保证” 课程ppt&#xff0c;仅供学习交流使用&#xff0c;谢谢。 程序图 程序图定义 程序图P&#xff08;V,E&#xff09;&#xff0c;V是节点的集合&#xff08;节点是程序中的语句或语句片段&#xff09;&#xff0c;E是有向边的集合…

分析 系统滴答时钟(tickClock),设置72MHz系统周期,如何实现1毫秒的系统时间?

一、CubeMX相关配置 1.1 相关引脚配置 1.2 相关时钟数配置 1.3 打开程序源码 二、相关函数分析

基于Java Springboot奶茶点餐微信小程序

一、作品包含 源码数据库万字文档全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA,微信开发者工具 数据…

centos8:Could not resolve host: mirrorlist.centos.org

【1】错误消息&#xff1a; [rootcentos211 redis-7.0.15]# yum update CentOS Stream 8 - AppStream …

宏海科技募资额有所缩减,最大销售和采购都重度依赖美的集团

《港湾商业观察》施子夫 11月29日&#xff0c;北交所上市审核委员会将召开2024年第24次上市委审议会议&#xff0c;届时将审议武汉宏海科技股份有限公司&#xff08;以下简称&#xff0c;宏海科技&#xff09;的首发上会事项。 在上会之前&#xff0c;宏海科技共收到北交所下…