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

【Linux】Socket编程——TCP版

📝前言:

上篇文章我们讲解了UDP编程,这篇文章我们来讲讲TCP编程

🎬个人简介:努力学习ing
📋个人专栏:Linux
🎀CSDN主页 愚润求学
🌄其他专栏:C++学习笔记,C语言入门基础,python入门基础,C++刷题专栏


目录

  • 一,TCP介绍
  • 二,重要接口
    • socket
    • bind
      • addr填充
    • listen
    • accept
    • connect
    • recv和send
    • 工作流程
  • 三,代码练习

一,TCP介绍

  • 在 UDP 通信中,客户端不需要与服务端建立连接,可直接将数据封装成 UDP 数据报发送出去。如果服务端没有准备好接收(比如没有启动监听或者监听的端口错误等 ),那么发送过去的数据报就会被丢弃,从而导致数据丢失
  • TCP(Transmission Control Protocol,传输控制协议)是面向连接的、可靠的传输层协议。在进行数据传输之前,需要通过 “三次握手” 建立连接,确保服务端处于可接收数据的状态
  • UDP直接获取的套接字就是和客户端通信的套接字,但是TCP需要获取两个套接字,一个是监听的,一个是通信的。

二,重要接口

socket

在这里插入图片描述

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

bind

在这里插入图片描述

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

addr填充

addr 参数是这样初始化

memset(&_addr, 0, sizeof(_addr)); // 清空
_addr.sin_family = AF_INET; // 填协议家族
_addr.sin_port = htons(_port); // 端口
// 这个 _ip 是一个点分10进制的 string ip 
inet_pton(AF_INET, _ip.c_str(), &_addr.sin_addr); // IP// 或者:_addr.sin_addr.s_addr = INADDR_ANY; // 用于服务端监听所有IP

listen

在这里插入图片描述

  • 用于将套接字设置为监听状态,等待客户端连接。
  • sockfd:要监听的套接字文件描述符(通常是 socket 创建并 bind 绑定过的)。
  • backlog:等待连接队列的最大长度(即最多允许多少个客户端处于“等待连接”状态)。
  • listen 后,套接字变为被动监听状态,不能直接收发数据,只能用来接收连接。只有调用了 listen,后续才能用 accept 接收客户端连接

accept

在这里插入图片描述
参数

  • sockfd:服务器端的监听 socket 描述符(通过 socket() 创建并通过 bind() 绑定、listen() 监听的 socket)。
  • addr:用于存储客户端的地址信息,是一个输出参数。
  • addrlen:输入输出参数,传入时表示 addr 缓冲区的大小,返回时表示实际存储的地址信息长度。

返回值

  • 成功:返回一个新的 socket 描述符,用于与该客户端进行数据收发(读写操作)
  • 失败:返回 -1,并设置 errno 表示错误原因。

注意

  • accept() 是阻塞函数,会一直等待直到有连接到来(非阻塞模式除外)。
  • 原监听 socket 用于监听新连接,而 accept() 返回的新 socket 才用于与特定客户端通信。
  • 一个服务器通常会循环调用 accept() 来处理多个个客户端的连接请求。

accept() 就像服务器的 “接待员”,负责接待新来的客户端并安排专门的 “服务员”(新的 socket)为其服务,而自己则继续等待下一位客人

connect

connect() 函数主要用于客户端,用于向服务器发起连接请求
在这里插入图片描述

参数

  • sockfd:客户端创建的 socket 描述符(通过 socket() 函数生成,尚未连接)。
  • addr:指向服务器地址信息的结构体指针(需包含服务器的 IP 地址和端口号)
  • addrlen:addr 结构体的字节长度(例如 sizeof(struct sockaddr_in))。

返回值:

  • 成功:返回 0,表示 TCP 三次握手完成,连接建立成功。
  • 失败:返回 -1,并设置全局变量 errno 指示错误原因(例如
    ECONNREFUSED 表示连接被拒绝,ETIMEDOUT 表示超时)。

recv和send

建立好连接以后,我们用recv来接受信息,有别于UDP的recvfrom(发送也类似,TCP 用 send(),UDP用sendto()):

  • recv 不需要指定发送方地址,因为在面向连接的通信中,连接建立后已经知道对方地址
  • recvfrom 必须提供 src_addr 参数来存储发送方的地址信息,这对于无连接通信至关重要,因为每次接收数据可能来自不同的发送方
// recv 函数
ssize_t recv(int sockfd, void *buf, size_t len, int flags);// recvfrom 函数
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);

工作流程

  • 服务器先创建监听 socket(socket()),绑定地址(bind()),并开始监听端口(listen())。
  • 调用 accept() 阻塞等待客户端连接。
  • 当客户端调用 connect() 发起连接后,accept() 返回新的 socket 描述符。
  • 服务器使用新的 socket 与客户端通信(recv()/send()),而原监听 socket 继续等待其他客户端连接。

三,代码练习

简答的回声:Github链接


🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!

http://www.xdnf.cn/news/1367551.html

相关文章:

  • 深入OpenHarmony后台任务“黑匣子”:BackgroundTaskMgr框架全栈解析与实战避坑指南
  • Thingsboard 租户管理员权限,增加租户普通用户权限
  • 三、显示3D文字
  • PLC通讯中遇到的实际场景
  • Mamba-HoME:面向3D医学影像分割的层次化专家混合新框架
  • 自然处理语言NLP: 基于双分支 LSTM 的酒店评论情感分析模型构建与实现
  • 透视光合组织大会:算力生态重构金融AI落地新实践
  • C语言 指针
  • 【设计模式】 面向对象基础
  • 打破技术壁垒的先进制造框架的智慧工业开源了
  • 如何利用ArcGIS探究环境与生态因子对水体、土壤、大气污染物的影响?
  • Mac安装mitmproxy及操作对监控的请求
  • Android Glide常见问题解决方案:从图片加载到内存优化
  • 使用 Docker、Jenkins、Harbor 和 GitLab 构建 CI/CD 流水线
  • Linux文件系统深入解析:从原理到实践
  • 通义灵码插件——AI 重构表单开发!半小时搭建可视化拖拽系统,效率碾压传统模式
  • 面试:Spring
  • MySQL 面试题系列(三)
  • week5-[循环结构]听歌
  • cuda编程笔记(16)--使用 cuDNN 实现卷积、激活、池化等反向操作
  • 淘宝/天猫商品详情API数据解析【附代码】
  • AP8105 PFM升压芯片数据手册
  • 支持向量机(SVM)学习笔记
  • 如何安装 VS2019 和 .NET Core SDK 2.2.301(winx64)?完整操作步骤(附安装包下载)
  • Ubuntu22.04安装OBS
  • 【软考论文】论自动化测试方法及其应用
  • 办公无纸化的关键:cpolar让Paperless-ngx远程扫描更便捷
  • 【Elasticsearch】k-NN 搜索深度解析:参数优化与分数过滤实践
  • 【SystemUI】锁屏来通知默认亮屏Wake模式
  • 32.Ansible平台搭建