TCP和UDP通信基础
目录
1. 套接字 (Socket)
2. 基于TCP通信的流程
服务器端
客户端
1. TCP通信API
1.1 创建套接字描述符socket
1.2 绑定IP和端口号bind
1.3 设置监听状态 listen
1.4 接受连接请求 accept
1.5 发送数据 send
1.6 接收数据 recv
2. TCP服务器代码示例
代码解释:
注意点:
3. 客户端API
连接服务器
功能:
参数说明:
返回值:
示例:
代码解释:
注意事项:
1. 套接字 (Socket)
-
套接字的本质
socket套接字是一个特殊的文件,在原始Linux中,它与管道、消息队列、共享内存、信号等机制类似,只能用于主机内的进程间通信。
-
历史发展与通信范围
- 随着TCP/IP协议族的出现,
socket套接字能够通过网卡,与外部主机进行通信,突破了单机限制。
- 随着TCP/IP协议族的出现,
-
socket函数的作用- 调用
socket函数会生成一个文件描述符。 - 主机间的不同进程可以通过对该文件描述符的读写,实现通信。
- 调用

2. 基于TCP通信的流程

服务器端
-
socket-
创建原始套接字。
-
-
bind- 将原始套接字与主机IP绑定(该服务器的身份,服务器以字节主机的身份通信)。
- 通过
bind,服务器的套接字被绑定到一个明确的IP地址和端口号。 - 当客户端发起通信请求时,客户端通过这个IP地址和端口号找到服务器,从而使服务器在网络中以“唯一身份”进行通信。
- 通过
- 将原始套接字与主机IP绑定(该服务器的身份,服务器以字节主机的身份通信)。
-
listen- 将原始套接字设置为监听状态。
- 注意:监听套接字只能用于监听,要进行实际通信需要创建一个新的套接字。
-
accept- 接收客户端的连接请求,获取客户端信息,并生成一个新的套接字描述符,用于与该客户端通信。
-
通信与关闭
- 使用新套接字发送和接收信息。
- 完成通信后关闭套接字。
客户端
-
socket- 创建原始套接字。
-
bind(可选)- 客户端可以选择是否绑定IP和端口号。
- 如果绑定,则客户端只能以绑定的IP和端口号进行通信。通常情况下无需绑定,除非服务器要求接收特定客户端的信息。
-
connect- 向服务器发送连接请求,并携带客户端的身份信息(IP和端口号)。
-
通信与关闭
- 通过套接字发送和接收信息。
- 完成通信后关闭套接字。
1. TCP通信API
1.1 创建套接字描述符socket
#include <sys/types.h>
#include <sys/socket.h>int socket(int domain, int type, int protocol);
- 功能:创建一个套接字描述符。
- 参数:
domain:通信域类型
AF_UNIX,AF_LOCAL: 本地通信AF_INET: IPv4通信AF_INET6: IPv6通信type:通信类型
SOCK_STREAM: 使用TCP通信协议SOCK_DGRAM: 使用UDP通信协议protocol:通常为0,表示自动选择与domain和type兼容的协议。- 返回值:成功返回套接字描述符,失败返回-1。
1.2 绑定IP和端口号bind
#include <sys/types.h>
#include <sys/socket.h>int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
- 功能:将套接字与IP和端口绑定,指定通信域。
- 参数:
sockfd:套接字文件描述符。addr:通信域的结构体指针,通常是struct sockaddr_in,其中包含IP地址和端口号。addrlen:结构体的大小。- 返回值:成功返回0,失败返回-1。
1.3 设置监听状态 listen
#include <sys/types.h>
#include <sys/socket.h>int listen(int sockfd, int backlog);
- 功能:设置套接字为监听状态,等待客户端连接。
- 参数:
sockfd:套接字描述符。backlog:最大等待连接数,最多为128。- 返回值:成功返回0,失败返回-1。
1.4 接受连接请求 accept
#include <sys/types.h> #include <sys/socket.h>int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
- 功能:从监听队列中接受客户端连接,创建新的套接字用于通信。
- 参数:
sockfd:监听套接字描述符。addr:客户端信息结构体(struct sockaddr_in),接受客户端信息。addrlen:客户端信息结构体的大小。- 返回值:成功返回新套接字描述符,失败返回-1。
1.5 发送数据 send
#include <sys/types.h>
#include <sys/socket.h>ssize_t send(int sockfd, const void *buf, size_t len, int flags);
- 功能:向其他进程发送数据。
- 参数:
sockfd:新套接字文件描述符。buf:发送的数据缓冲区。len:发送的数据长度。flags:控制发送的标志(例如MSG_DONTWAIT表示非阻塞发送)。- 返回值:成功返回发送的字节数,失败返回-1。
1.6 接收数据 recv
#include <sys/types.h>
#include <sys/socket.h>ssize_t recv(int sockfd, void *buf, size_t len, int flags);
- 功能:从其他进程接收数据。
- 参数:
sockfd:新套接字文件描述符。buf:接收数据的缓冲区。len:接收数据的最大长度。flags:控制接收的标志(例如MSG_DONTWAIT表示非阻塞接收)。- 返回值:成功返回接收的字节数,失败返回-1。
2. TCP服务器代码示例
#include <myhead.h> #define IP "192.168.60.69" #define PORT 6666 #define BACKLOG 20int main(int argc, const char *argv[]) {// AF_INET: IPV4通信// SOCK_STREAM:TCP通信协议int oldfd = socket(AF_INET, SOCK_STREAM, 0); // 1. 创建套接字if (oldfd == -1){perror("socket");return -1;}// 2. 绑定IP和端口号struct sockaddr_in server = {.sin_family = AF_INET, // IPV4.sin_port = htons(PORT), // 端口号转为网络字节序.sin_addr.s_addr = inet_addr(IP), // IP地址};if (bind(oldfd, (struct sockaddr *)&server, sizeof(server)) == -1){perror("bind");return -1;}// 3. 监听if (listen(oldfd, BACKLOG) == -1){perror("listen");return -1;}// 4. 接受客户端连接请求,创建新的描述符用于通信struct sockaddr_in client; // 接收客户端信息的结构体socklen_t client_len = sizeof(client); // 计算出结构体大小int newfd;newfd = accept(oldfd, (struct sockaddr *)&client, &client_len);if (newfd == -1){perror("accept");return -1;}printf("%s发来连接请求\n", inet_ntoa(client.sin_addr));// 5. 循环收发信息char buff[1024];while (1){memset(buff, 0, sizeof(buff));// int len = read(newfd, buff, sizeof(buff)); // 传统方式int len = recv(newfd, buff, sizeof(buff), 0); // 0: 阻塞发送,MSG_DONTWAIT: 非阻塞if (len == 0){printf("客户端下线\n");break;}printf("%s\n", buff);strcat(buff, "5201314"); // 加上一句话回过去// write(newfd, buff, sizeof(buff)); // 传统方式send(newfd, buff, sizeof(buff), 0); // 发送}close(oldfd);close(newfd);return 0; }
代码解释:
- 创建套接字:
socket(AF_INET, SOCK_STREAM, 0)创建一个支持 IPv4 的 TCP 套接字。- 绑定 IP 和端口:通过
bind函数将服务器的 IP 地址和端口号绑定到创建的套接字上。- 监听:调用
listen函数将套接字设置为监听状态,BACKLOG指定了等待连接队列的最大长度。- 接受客户端连接:
accept函数用于从等待队列中接收客户端的连接请求,返回一个新的套接字文件描述符用于与客户端进行通信。- 收发信息:使用
recv接收客户端发来的信息,并通过send发送响应。消息中添加了"5201314"字符串后回传给客户端。- 关闭套接字:完成通信后,通过
close关闭原始套接字和客户端套接字。
注意点:
recv和send用于数据传输,它们是基于 TCP 协议的,保证数据的可靠传输。inet_ntoa函数用于将客户端的 IP 地址转换为点分十进制格式。- 使用
strcat拼接字符串发送回客户端。
3. 客户端API
连接服务器
#include <sys/types.h> /* See NOTES */ #include <sys/socket.h>int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
功能:
connect用于客户端与服务器建立连接。它对应于服务器端的accept函数,完成了三次握手的过程。- 客户端通过调用
connect向服务器发送连接请求,服务器通过accept接受连接。此时,TCP连接的三次握手完成。
参数说明:
- 参数1 (
sockfd):套接字描述符,即客户端通过socket函数创建的套接字。- 参数2 (
addr):服务器的地址结构体,包含目标服务器的 IP 地址和端口号。- 参数3 (
addrlen):addr结构体的大小,用于指定服务器地址结构体的大小。
返回值:
- 成功:返回 0。
- 失败:返回 -1,并置位错误码。
示例:
#include <sys/socket.h> #include <arpa/inet.h> #include <stdio.h>#define SERVER_IP "192.168.60.69" #define SERVER_PORT 6666int main() {int sockfd = socket(AF_INET, SOCK_STREAM, 0); // 创建套接字if (sockfd == -1) {perror("socket");return -1;}struct sockaddr_in server_addr;server_addr.sin_family = AF_INET; // IPV4server_addr.sin_port = htons(SERVER_PORT); // 服务器端口server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); // 服务器IP// 连接到服务器if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {perror("connect");return -1;}printf("成功连接到服务器\n");// 这里可以添加发送和接收数据的代码close(sockfd); // 关闭套接字return 0; }
代码解释:
- 创建套接字:客户端使用
socket函数创建一个 TCP 套接字。- 填充服务器地址结构体:
struct sockaddr_in用于定义目标服务器的 IP 地址和端口号。- 建立连接:客户端调用
connect函数连接到指定服务器。如果连接成功,将输出"成功连接到服务器"。- 关闭套接字:连接完成后,使用
close关闭套接字。
注意事项:
- 连接过程中的三次握手是自动进行的,客户端不需要手动处理三次握手的细节。
- 如果连接失败(例如服务器不可达或端口未打开),
connect将返回 -1,并设置相应的错误码。
相关文章:
TCP和UDP通信基础
目录 1. 套接字 (Socket) 2. 基于TCP通信的流程 服务器端 客户端 1. TCP通信API 1.1 创建套接字描述符socket 1.2 绑定IP和端口号bind 1.3 设置监听状态 listen 1.4 接受连接请求 accept 1.5 发送数据 send 1.6 接收数据 recv 2. TCP服务器代码示例 代码解释&…...
微服务中的技术使用与搭配:如何选择合适的工具构建高效的微服务架构
一、微服务架构中的关键技术 微服务架构涉及的技术非常广泛,涵盖了开发、部署、监控、安全等各个方面。以下是微服务架构中常用的一些技术及其作用: 1. 服务注册与发现 微服务架构的一个重要特性是各个服务是独立部署的,因此它们的地址&am…...
找出字符串第一个匹配项的下标
找出字符串第一个匹配项的下标 题目描述: 题解思路: 图上所示,利用字符滑动,如果匹配就字符开始移动;如果不匹配成功,则停止移动,并回到字符串刚开始匹配的字符下标前一个,为下一次…...
面向FWA市场!移远通信高性能5G-A模组RG650V-NA通过北美两大重要运营商认证
近日,全球领先的物联网整体解决方案供应商移远通信宣布,其旗下符合3GPP R17标准的新一代5G-A模组RG650V-NA成功通过了北美两家重要运营商认证。凭借高速度、大容量、低延迟、高可靠等优势,该模组可满足CPE、家庭/企业网关、移动热点、高清视频…...
Matlab实现北方苍鹰优化算法优化随机森林算法模型 (NGO-RF)(附源码)
目录 1.内容介绍 2.部分代码 3.实验结果 4.内容获取 1内容介绍 北方苍鹰优化算法(Northern Goshawk Optimization, NGO)是一种新颖的群智能优化算法,灵感源自北方苍鹰捕食时的策略。该算法通过模拟苍鹰的搜寻、接近和捕捉猎物的行为模式&am…...
搭建环境 配置编译运行 mpi-test-suite
1,编译安装 ucx 下载源码: $ git clone https://github.com/openucx/ucx.git $ git checkout v1.17.0 运行auto工具: $ ./autogen.sh $ ./autogen.sh 指所以运行两次是因为有时候第一次会失败,原因未查。 配置 ucx $ m…...
夜神模拟器启动报错:虚拟机启动失败 请进行修复 关闭hyper-v
不是关闭hyper-v的问题。 点那个没用。 解决办法: 我电脑win11(win10 win11都一样 )去安全中心-设备安全性 把内存完整性关了。 这还不够。 在右上角找系统信息 我发现VT显示没开 于是我去BIOS中开启VT 这个VT怎么开很简单。就是你F2 F1…...
投资策略规划最优决策分析
目录 一、投资策略规划问题详细 二、存在最优投资策略:每年都将所有钱投入到单一投资产品中 (一)状态转移方程 (二)初始条件与最优策略 (三)证明最优策略总是将所有钱投入到单一投资产品中…...
一篇保姆式虚拟机安装ubantu教程
前言: 本文将介绍在VMware安装ubantu,会的人可以试试上一篇介绍centos/ubantu安装docker环境,不同环境安装docker。一篇保姆式centos/unbantu安装docker 官网下载iso:Ubuntu 18.04.6 LTS (Bionic Beaver) 本次使用的版本是: 一&…...
缓冲区的奥秘:解析数据交错的魔法
目录 一、理解缓存区的好处 (一)直观性的理解 (二)缓存区的好处 二、经典案例分析体会 (一)文件读写流(File I/O Buffering) BufferedOutputStream 和 BufferedWriter 可以加快…...
CentOS 7.9 搭建本地Yum源
yum(Yellow Dog Updater,Modified)是一个在Fedora、Centos、RedHat中的Shell前端软件包管理器。基于RPM包管理,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖关系,并且一次安装所有依赖的软件…...
【Python】爬虫实战:高效爬取电影网站信息指南(涵盖了诸多学习内容)
本期目录 1 爬取思路 2 爬虫过程 2.1 网址 2.2 查看网页代码 3 爬取数据 3.1 导入包 3.2 爬取代码 01 爬取思路 \*- 第一步,获取页面内容\*- 第二步:解析并获取单个项目链接 \*- 第三步:获取子页面内容 \*- 第四步:解析…...
MATLAB和C++及Python流式细胞术
🌵MATLAB 片段 流式细胞术(Flow Cytometry)是一种用于分析细胞或其他颗粒悬浮在流动介质中的方法。MATLAB 可以用来处理和分析流式细胞术的数据,例如用于数据预处理、可视化和分析。以下是一些常见的 MATLAB 处理流式细胞术数据的…...
Vue3 pinia使用
Pinia 是一个现代的状态管理库,专为 Vue 3 设计。它提供了一种简单、直观的方式来管理应用中的全局状态 (就是不同组件都希望去共享的一些变量,函数等)。Pinia 的设计灵感来自于 Vuex(Vue 2 的状态管理库),但进行了许多改进&#…...
tdengine学习笔记-建库和建表
目录 建库和建表 创建超级表 创建表 自动建表 创建普通表 多列模型 VS 单列模型 数据类型映射 示例程序汇总 在车联网领域的应用 1. 数据模型概述 2. 表结构设计 2.1 静态数据表 2.2 动态数据表 4. 查询数据 4.1 查询单个车辆的数据 4.2 查询多个…...
Django数据迁移出错,解决raise NodeNotFoundError问题
错误出现在: raise NodeNotFoundError(self.error_message, self.key, originself.origin) django.db.migrations.exceptions.NodeNotFoundError: Migration myApp.0003_alter_jobinfo_practise dependencies reference nonexistent parent node (myApp, 0002_renam…...
景联文科技:以全面数据处理服务推动AI创新与产业智能化转型
数据标注公司在人工智能领域扮演着重要角色,通过提供高质量的数据标注服务,帮助企业和组织训练和优化机器学习模型。从需求分析到数据交付,每一个步骤都需要严格把控,确保数据的质量和安全性。 景联文科技是一家专业的数据采集与标…...
MySQL学习/复习7表的内外连接
一、内连接...
Spring Cloud入门笔记2(OpenFeign)
场景: OpenFeign中集成了LoadBalancer,并简化了微服务调用,所以实际上使用该技术 技术栈:OpenFeign 步骤一:导入依赖 <!--openfeign--> <dependency><groupId>org.springframework.cloud</groupId><a…...
小程序中模拟发信息输入框,让textarea可以设置最大宽以及根据输入的内容自动变高的方式
<textarea show-confirm-bar"{{false}}" value"{{item.aValue}}" maxlength"301" placeholder"请输入" auto-height"{{true}}" bind:blur"onBlurTextarea" focus"{{true}}" bindinput"…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
