TCP的服务监听步骤(等待客户端连接前)

TCP 服务器通过以下步骤完成从初始化到等待客户端连接,为后续的数据传输(send()/recv())奠定了基础

一、创建套接字(Socket)

  • 作用:套接字是网络通信的端点,用于标识通信中的双方(IP 地址和端口号)。服务器首先需要创建一个套接字,作为后续监听和通信的基础。
  • 实现:应用程序通过系统调用(如socket())创建套接字,指定地址族(如 IPv4 用AF_INET)、传输层协议(TCP 用SOCK_STREAM)等参数。
  • 示例:在 Linux 中,int sockfd = socket(AF_INET, SOCK_STREAM, 0); 会创建一个 TCP 套接字,返回套接字描述符sockfd

二、绑定套接字到本地地址和端口(Bind)

  • 作用:将创建的套接字与服务器的本地 IP 地址和指定端口号绑定,确保客户端能通过该地址和端口找到服务器。
  • 实现
    1. 应用程序定义一个包含本地 IP 地址和端口号的结构体(如sockaddr_in)。
    2. 通过系统调用(如bind())将套接字与该结构体绑定。
  • 注意
    • 端口号通常选择 1024 以上的非特权端口(避免与系统服务冲突)。
    • 若 IP 地址设为INADDR_ANY(通配地址),表示服务器监听所有可用的本地网络接口。
  • 示例bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));

三、设置监听状态(Listen)

  • 作用:将绑定后的套接字转换为监听套接字,使其能够接收客户端的连接请求。同时,操作系统会为该套接字维护一个连接请求队列(未完成三次握手的客户端请求)。
  • 实现:通过系统调用(如listen())设置监听,参数包括监听套接字和队列的最大长度(backlog,即最多能同时等待处理的连接请求数)。
  • 注意backlog的值需根据服务器性能和预期并发量设置,若队列满,新的连接请求会被拒绝(客户端可能收到 “连接超时” 错误)。
  • 示例listen(sockfd, 5);(表示最多允许 5 个连接请求在队列中等待)。

四、等待并接受客户端连接(Accept)

  • 作用:监听套接字进入阻塞状态(默认情况),等待客户端的连接请求。当有客户端发起连接时,服务器通过accept()系统调用接受连接,生成一个新的连接套接字用于与该客户端通信。
  • 过程
    1. 客户端通过connect()发起 TCP 连接请求,与服务器进行三次握手。
    2. 三次握手完成后,连接请求从 “未完成队列” 移至 “已完成队列”。
    3. 服务器调用accept()从 “已完成队列” 中取出一个连接请求,创建新的连接套接字(与监听套接字的 IP 和端口相同,但用于单独的客户端通信)。
  • 注意
    • 监听套接字始终保持监听状态,用于接收新的连接请求;连接套接字则用于与特定客户端的数据传输。
    • 若需处理并发连接,服务器通常会通过多线程、多进程或 I/O 复用(如selectepoll)来同时管理多个连接套接字。
  • 示例int new_fd = accept(sockfd, (struct sockaddr*)&client_addr, &addr_len);new_fd即为新的连接套接字)。

总结:TCP 服务监听的完整流程

  1. 创建套接字(socket())→ 2. 绑定地址和端口(bind())→ 3. 设置监听(listen())→ 4. 接受连接(accept())。

服务端与客户端通信(3握手4挥手)

TCP 通信遵循 "三次握手建立连接、数据传输、四次挥手断开连接" 的经典模式,这种模式确保了通信的可靠性和有序性。

1. 连接建立:三次握手

TCP 是面向连接的协议,在进行实际数据传输前,通信双方必须先建立连接,这个过程被形象地称为 "三次握手"(Three-way Handshake)。

  • 第一次握手:客户端发送 SYN(同步序列编号)报文段,告知服务器客户端的初始序列号(ISN),并请求建立连接。
  • 第二次次握手:服务器收到 SYN 后,返回一个 SYN+ACK(确认)报文段,包含服务器的初始序列号,并确认收到客户端的 SYN(ACK 值 = 客户端 ISN+1)。
  • 第三次握手:客户端收到服务器的 SYN+ACK 后,发送一个 ACK 报文段,确认收到服务器的 SYN(ACK 值 = 服务器 ISN+1)。

三次握手完成后,TCP 连接正式建立,双方可以开始数据传输。这种设计有效防止了因网络延迟导致的 "已失效的连接请求报文段" 被服务器接收,从而避免资源浪费。

2. 数据传输阶段

连接建立后,进入数据传输阶段。TCP 通过以下机制保证数据传输的可靠性:

  • 序列号与确认机制:每个数据字节都有一个序列号,接收方收到数据后会返回确认信息,告知发送方已成功接收的数据量。
  • 超时重传:发送方设置超时计时器,若在规定时间内未收到确认,则重传数据。
  • 流量控制:通过滑动窗口机制,控制发送方的发送速率,避免接收方缓冲区溢出。
  • 拥塞控制:检测网络拥塞状态并调整发送速率,避免网络过载。

3. 连接终止:四次挥手

当通信结束需要断开连接时,TCP 使用 "四次挥手"(Four-way Wavehand)过程:

  • 第一次挥手:主动关闭方发送 FIN(结束)报文段,告知对方要关闭连接。
  • 第二次挥手:被动关闭方收到 FIN 后,返回 ACK 确认,此时主动关闭方到被动关闭方的连接半关闭。
  • 第三次挥手:被动关闭方准备好关闭连接后,也发送一个 FIN 报文段。
  • 第四次挥手:主动关闭方收到 FIN 后,返回 ACK 确认,被动关闭方到主动关闭方的连接也半关闭。等待一段时间确保确认报文送达后,连接完全关闭。

四次挥手的设计是因为 TCP 连接是全双工的,允许双方独立关闭各自的发送通道。

服务端的全流程

1. 调用 socket 函数创建 socket(监听socket)
2. 调用 bind 函数 将 socket绑定到某个ip和端口的二元组上
3. 调用 listen 函数 开启侦听
4. 当有客户端请求连接上来后,调用 accept 函数接受连接,产生一个新的 socket(客户端 socket)
5. 基于新产生的 socket 调用 send 或 recv 函数开始与客户端进行数据交流
6. 通信结束后,调用 close 函数关闭监听 socket

1. 三次握手(建立连接)发生在第 4 步:accept() 函数执行期间

  • 当服务器调用 listen() 后,进入 “监听” 状态,内核会维护两个队列:
    • 未完成连接队列:客户端已发送 SYN 但三次握手未完成的请求。
    • 已完成连接队列:三次握手已完成、等待服务器处理的连接。
  • 当客户端调用 connect() 发起连接时,内核会自动完成三次握手:
    1. 客户端发送 SYN → 服务器内核接收并放入未完成队列,返回 SYN+ACK(第二次握手)。
    2. 客户端返回 ACK(第三次握手)→ 服务器内核将连接从 “未完成队列” 移至 “已完成队列”。
  • 此时服务器调用 accept() 函数,只是从 “已完成队列” 中取出一个已建立的连接,并创建新的客户端 socket。三次握手的整个过程由内核在 listen() 之后、accept() 返回之前自动完成,应用程序无需干预。

2. 四次挥手(断开连接)发生在数据传输结束后,由 close() 函数触发

  • 当通信双方(客户端或服务器)决定结束连接时,调用 close() 函数会触发内核执行四次挥手:
    1. 主动关闭方调用 close() → 内核发送 FIN 报文(第一次挥手)。
    2. 被动关闭方收到 FIN 后,内核自动返回 ACK(第二次挥手),此时主动关闭方向被动关闭方的连接 “半关闭”。
    3. 被动关闭方处理完剩余数据后,调用 close() → 内核发送 FIN 报文(第三次挥手)。
    4. 主动关闭方收到 FIN 后,内核自动返回 ACK(第四次挥手),等待超时后连接完全关闭。
  • 注意:通常服务器会先关闭 “客户端 socket”(与单个客户端的连接),最后再关闭 “监听 socket”(停止接受新连接)。四次挥手由内核在 close() 调用后自动完成,应用程序只需调用 close() 触发这个过程。

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

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

相关文章

数据结构 双链表与LinkedList

本节目标: 认识并且能够实现一个双链表认识LinkedList类并且知道如何去使用 1.双链表 概念 在数据结构中,双链表(Doubly Linked List) 是一种常见的线性数据结构,它由一系列节点组成,每个节点不仅包含数据…

如何解决 JetBrains IntelliJ IDEA 2024.2 和 2025.2 新版本区域选择问题:key is invalid

如何解决 JetBrains IntelliJ IDEA 2024.2 和 2025.2 新版本区域选择问题:key is invalid 在 JetBrains 发布的 IntelliJ IDEA、PyCharm 2024.2 和 2025.2 新版本中,增加了一个新的功能——区域选择。在设置菜单中,你可以找到这一选项&#…

GSON 框架下百度天气 JSON 数据转 JavaBean 的实战攻略

目录 前言 一、百度天气JSON 1、请求参数 2、返回参数 3、属性映射 二、GSON属性映射实战 1、类对象映射 2、属性字段映射 3、日期数据映射 三、天气接口对象展示 1、接口调用 2、Java属性打印输出 四、总结 前言 在当今数字化时代,数据的高效处理与转换…

NAS技术在县级融媒体中心的架构设计与安全运维浅析

NAS技术在县级融媒体中心的架构设计与安全运维浅析 ——原理剖析、应用实践与防御体系建设作者:高级网络安全工程师 吉林•镇赉融媒 刘晓伟 最后更新:2025年8月 适用对象:媒体行业网络安全从业者一、NAS技术核心原理剖析 1. 基础架构 NAS&am…

CobaltStrike的搭建和使用

下载CobaltStrike环境建议使用jdk17,其他java版本有些功能可能无法使用通过网盘分享的文件:CS4.7key-mht.zip 链接: https://pan.baidu.com/s/1CRd1x4r6EIk14BD3UCLgxw?pwdevf4 提取码: evf4将下载的文件分别放在服务器和 本地/kali 上 也就是服务器为…

【Altium designer】一键给多个器件添加参数

目的: 一键给N个元器件/Part添加参数和修改参数值,比如一键给多个电阻添加“备注”并赋予备注的内容为“不焊接”,或者更改“备注”的内容为“不焊接”或空。 背景: 刚入门用AD画原理图,因为原理图的电阻、电容和芯片等等的冗余/兼容设计太多,增加备注不焊的元器件位号…

熟练掌握switch语句:技巧与运用

目录 一、switch语句基础 基本语法结构: 在C/C中: 注意事项: 二、if与switch语句对比 示例:计算整数除以3的余数 使用if语句实现: 使用switch语句实现: 三、break语句的作用 示例(无br…

【03】厦门立林科技——立林科技 嵌入式 校招笔试,题目记录及解析

厦门立林科技——立林科技 嵌入式 校招笔试,题目记录及解析 1.下面的程序的输出是()。2.在头文件中#ifndef/#define/#endif的作用是4.执行下面程序中的输出语句后,输出的结果是()6.在32位处理器上,运行如下程序后p的值为()。10.设有两字符串“…

C++算法(数据结构)版

C算法(数据结构)版 有些题目不是完整的题目,如需查看完整的题目请移步到acwing的算法基础课中 文章目录C算法(数据结构)版单链表思路:双链表思路:栈思路:队列思路:单调栈…

算法训练营DAY57 第十一章:图论part07

prim算法精讲 53. 寻宝(第七期模拟笔试) 题目描述: 在世界的某个区域,有一些分散的神秘岛屿,每个岛屿上都有一种珍稀的资源或者宝藏。国王打算在这些岛屿上建公路,方便运输。 不同岛屿之间,…

最短路问题从入门到负权最短路

一,BFS层次最短路/*题目描述 题目描述 给出一个 N 个顶点 M 条边的无向无权图,顶点编号为 1∼N。 问从顶点 1 开始,到其他每个点的最短路有几条。 输入格式 第一行包含 2 个正整数 N,M,为图的顶点数与边数。 接下来 M 行&#xff…

AI智能体小白入门指南

AI智能体小白入门指南 ——什么是AI智能体?它们如何工作? 一、AI智能体是什么? AI智能体(AI Agent)是能感知环境、自主决策并执行动作的人工智能系统。 类比理解:像一个“虚拟机器人”或“数字助手”&#…

《设计模式》策略模式

1.策略模式定义 策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一组算法,将每个算法封装起来,并使它们可以相互替换,从而让算法的变化独立于使用它的客户(Client)。 换…

AWS DMS 深度解析:从迁移任务到复制任务 - 全流程指南与最佳实践

AWS Database Migration Service (DMS) 是一项强大的云服务,用于在源数据库和目标数据库之间安全地迁移数据。其核心优势在于支持几乎零停机时间的迁移,这主要归功于其“变更数据捕获 (CDC)”功能。理解迁移任务 (Migration Task) 和复制任务 (Replication Task) 的关系与操作…

国企社招 | 中国邮政2025年社会招聘开启

添加图片注释,不超过 140 字(可选) 添加图片注释,不超过 140 字(可选) 添加图片注释,不超过 140 字(可选) 原文链接:“邮”你“政”好 | 广东邮政2025年社会…

linux添加自启动

linux添加自启动 配置步骤: 创建systemd服务文件 sudo nano /etc/systemd/system/tme-vod.service将下面artifact中的内容复制到该文件中。 [Unit] DescriptionTME VOD Service Afternetwork.target[Service] Typesimple Userroot Grouproot WorkingDirectory/data/…

轻量级解决方案:如何高效处理Word转PDF?

文档格式转换时,手动逐个处理总显得效率低下。它的体积小巧,不到1MB,且无界面设计,运行极简:将其与Word文件放入同一目录,双击启动,程序便会自动完成所有文档的PDF转换。操作零复杂度&#xff0…

Redis 数据倾斜

Redis 数据倾斜指的是在 Redis 集群模式下,数据(以及相应的访问请求和负载)在各个分片(Shard)之间分布严重不均匀的现象。这会导致部分节点成为热点或超载,而其他节点资源闲置,最终引发性能瓶颈…

Java基础-TCP通信(多发多收和一发一收)

目录 案例要求: 实现思路: 代码: User:客户端 Client:服务端 总结: 案例要求: 实现TCP通信的多发多收和一发一收,多发多收去掉各自的while循环就是一发一收,本文只模拟一发一收 实现思路: 客户端(U…

WinForm 对话框的 Show 与 ShowDialog:阻塞与非阻塞的抉择

目录 核心概念:阻塞与非阻塞 Show 与 ShowDialog 的详细对比 代码示例:两种方式的实现差异 使用 Show () 显示非模态对话框 使用 ShowDialog () 显示模态对话框 适用场景分析 适合使用 Show () 的场景 适合使用 ShowDialog () 的场景 最佳实践与…