当前位置: 首页 > news >正文

Socket 编程 TCP(准备阶段)

目录

TCP socket API 详解

socket():

bind():

listen():

accept():

先铺垫:TCP 通信的 “饭店经营逻辑”

accept 的返回值:“专门服务单个客人的服务员”

用饭店场景拆解:

关键对比:老板 vs 服务员(原始套接字 vs accept 返回的新套接字)

举个实际场景:

一句话总结:

connect


TCP socket API 详解

下面介绍程序中会用到的 socket API,这些函数都在 sys/socket.h 头文件中。

socket():

  • socket()打开一个网络通讯端口,如果成功的话,就像 open()一样返回一个文件描述符;
  • 应用程序可以像读写文件一样用 read/write 在网络上收发数据;
  • 如果 socket()调用出错则返回-1;
  • 对于 IPv4, family 参数指定为 AF_INET;
  • 对于 TCP 协议,type 参数指定为 SOCK_STREAM, 表示面向流的传输协议
  • protocol 参数的介绍从略,指定为 0 即可。

bind():

  • 服务器程序所监听的网络地址和端口号通常是固定不变的,客户端程序得知服务器程序的地址和端口号后就可以向服务器发起连接; 服务器需要调用 bind 绑定一个固定的网络地址和端口号;
  • bind()成功返回 0,失败返回-1。
  • bind()的作用是将参数 sockfd 和 myaddr 绑定在一起, 使 sockfd 这个用于网络通讯的文件描述符监听 myaddr 所描述的地址和端口号;
  • 我们在udp的时候讲过,struct sockaddr *是一个通用指针类型,myaddr 参数实际上可以接受多种协议的 sockaddr 结构体,而它们的长度各不相同,所以需要第三个参数 addrlen 指定结构体的长度;

我们的程序中对 myaddr 参数是这样初始化的:

  1. 将整个结构体清零;
  2. 设置地址类型为 AF_INET;
  3. 网络地址为 INADDR_ANY, 这个宏表示本地的任意 IP 地址,因为服务器可能有多个网卡,每个网卡也可能绑定多个 IP 地址, 这样设置可以在所有的 IP 地址上监听, 直到与某个客户端建立了连接时才确定下来到底用哪个 IP 地址;
  4. 端口号为 SERV_PORT, 我们定义为 8888,也就是在允许范围内可自定义;

listen():

  • listen()声明 sockfd 处于监听状态, 并且最多允许有 backlog 个客户端处于连接等待状态, 如果接收到更多的连接请求就忽略, 这里设置不会太大(一般是 5);
  • listen()成功返回 0,失败返回-1;

accept():

  • 三次握手完成后, 服务器调用 accept()接受连接;
  • 如果服务器调用 accept()时还没有客户端的连接请求,就阻塞等待直到有客户端连接上来;
  • addr 是一个传出参数,accept()返回时传出客户端的地址和端口号;
  • 如果给 addr 参数传 NULL,表示不关心客户端的地址;
  • addrlen 参数是一个传入传出参数(value-result argument), 传入的是调用者提供的, 缓冲区 addr 的长度以避免缓冲区溢出问题, 传出的是客户端地址结构体的实际长度(有可能没有占满调用者提供的缓冲区);

我们的服务器程序结构是这样的:

理解 accecpt 的返回值: 饭店拉客例子

用 “饭店拉客” 的场景类比 HTTP 中的 Accept 请求头和返回值,能非常直观地理解其核心逻辑 ——核心是区分 “招揽客人的老板” 和 “服务具体客人的服务员”。。

先铺垫:TCP 通信的 “饭店经营逻辑”

在 TCP 服务器编程中,socketbindlistenaccept 是一套 “开店流程”:

  1. socket():租下一间店面(创建套接字,是通信的基础 “资源”)。
  2. bind():给店面挂上门牌(绑定 IP 和端口,让客人知道去哪找你)。
  3. listen():打开店门、安排老板在门口拉客(进入 “监听状态”,等待客人上门)。
  4. accept():老板接到客人,喊来一个服务员专门伺候这位客人(核心动作,对应返回值的意义)。

accept 的返回值:“专门服务单个客人的服务员”

accept 函数的原型核心可以简化理解为:int accept(int 老板的编号, ...);

它的返回值是一个新的套接字描述符(可以理解为 “服务员的工号”),这个返回值的本质是:为 “刚刚上门的单个客户端” 创建的专属通信通道

用饭店场景拆解:
  • 参数里的 “老板”(listen 状态的套接字):老板的职责只有一个 —— 在门口监听、等待客人上门(对应 listen 后的套接字,只负责接收客户端的 connect 连接请求)。老板不直接服务客人,他的 “工号”(原始套接字描述符)是固定的,一直用于 “拉新客”。

  • 返回值的 “服务员”(新的套接字):当有客人(客户端)走到门口(发起 connect),老板(accept 函数)会做两件事:

    这个服务员(新套接字)的唯一作用,就是和这位特定客人单独通信—— 客人点单(客户端发数据,用 recv 读取)、服务员上菜(服务器发数据,用 send 发送),全程不影响老板继续在门口拉其他客人(原始套接字仍在监听新请求)。

    1. 确认 “客人要进店消费”(建立 TCP 连接的三次握手);
    2. 喊来一个专属服务员(返回新的套接字描述符),并告诉服务员:“这位客人交给你了,全程负责他的点单、上菜、结账”。
关键对比:老板 vs 服务员(原始套接字 vs accept 返回的新套接字)
角色对应套接字核心职责生命周期
老板listen 后的原始套接字只负责在门口监听、接收新连接请求贯穿整个服务器运行期间
服务员accept 返回的新套接字只负责和单个客户端的全程数据交互客户端断开连接后就 “下班”(关闭)

举个实际场景:

假设你开了一家 TCP 饭店(服务器):

  1. 老板(原始套接字 sockfd=3)在门口挂好门牌(bind 到 127.0.0.1:8080),打开门(listen)等待客人。
  2. 客人 A 上门(connect 请求),accept(sockfd, ...) 返回 new_sockfd=4(服务员 4 号)—— 服务员 4 号专门服务客人 A,负责他的所有需求。
  3. 同时,客人 B 也上门了,accept(sockfd, ...) 又返回 new_sockfd=5(服务员 5 号)—— 服务员 5 号专门服务客人 B,和服务员 4 号的工作互不干扰。
  4. 老板(sockfd=3)自始至终都在门口,继续等客人 C、D……

一句话总结:

accept 的返回值,就是 TCP 服务器为 “刚接进来的单个客户端” 分配的专属通信 “服务员” —— 它是后续和这个客户端收发数据的唯一 “接口”,而原始的监听套接字会继续负责 “拉新客”。

connect

  • 客户端需要调用 connect()连接服务器;
  • connect 和 bind 的参数形式一致, 区别在于 bind 的参数是自己的地址, 而 connect 的参数是对方的地址;
  • connect()成功返回 0,出错返回-1;
http://www.dtcms.com/a/414347.html

相关文章:

  • 【Ultralytics】评估报错:解决 KeyError: ‘info‘ 错误
  • 哪些是实名制网站母了猜猜看游戏做网站
  • 【Linux】TCP原理
  • 论文阅读:arxiv 2024 Fast Adversarial Attacks on Language Models In One GPU Minute
  • OpenJDK 17 方法链接与同步方法入口点生成机制深度解析
  • qt-C++笔记之自定义绘制:QWidget中的paintEvent 与 QGraphicsItem中的paint
  • 项目:智能排队控制系统
  • LeetCode:71.字符串解码
  • LeetCode:66.搜索旋转排序数组
  • 阿帕奇网站搭建六安做网站的
  • wordpress去除评论表单电子商务seo优化
  • deepseek kotlin flow快生产者和慢消费者解决策略
  • 20.NFS iSCSI服务器
  • uniapp 搭建vue项目,快速搭建项目
  • 自动网页浏览助手:基于 Selenium + GLM-4V 的百度自动搜索与内容提取系统
  • 网站地图什么时候提交好网站自响应
  • 深度学习笔记(一)——线性回归、Softmax回归、多层感知机、环境和分布偏移
  • 网站建设教程要去d湖南岚鸿询 问2022年企业年报网上申报流程
  • js构造函数—11
  • Kotlin轻量级互斥锁Mutext与轻量级信号量Semaphore异同比较
  • 【MySQL✨】MySQL 入门之旅 · 第十篇:数据库备份与恢复
  • k8s里三种探针的使用场景
  • 8.基于 Ingress-nginx-controller 实现 k8s 七层代理
  • Kling-Audio-Eval - 高质量视频到音频生成评估数据集
  • LeetCode 812.最大三角形的面积
  • 做网站都需要服务器吗域名类型
  • js逆向实战:爬取淘宝男装商品
  • 前端3.0
  • 机器视觉检测中,最小尺寸多少像素可以检测到?重点解析传统算法和深度学习,对比度很致命
  • 不同浏览器中高效维护需要登录网站的登录态