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

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)

  1. 套接字的本质

    • socket套接字是一个特殊的文件,在原始Linux中,它与管道、消息队列、共享内存、信号等机制类似,只能用于主机内的进程间通信。
  2. 历史发展与通信范围

    • 随着TCP/IP协议族的出现,socket套接字能够通过网卡,与外部主机进行通信,突破了单机限制。
  3. socket函数的作用

    • 调用socket函数会生成一个文件描述符。
    • 主机间的不同进程可以通过对该文件描述符的读写,实现通信。


2. 基于TCP通信的流程

服务器端

  1. socket

    • 创建原始套接字。

  2. bind

    • 将原始套接字与主机IP绑定(该服务器的身份,服务器以字节主机的身份通信)。
      • 通过bind,服务器的套接字被绑定到一个明确的IP地址和端口号。
      • 当客户端发起通信请求时,客户端通过这个IP地址和端口号找到服务器,从而使服务器在网络中以“唯一身份”进行通信。
  3. listen

    • 将原始套接字设置为监听状态。
    • 注意:监听套接字只能用于监听,要进行实际通信需要创建一个新的套接字。
  4. accept

    • 接收客户端的连接请求,获取客户端信息,并生成一个新的套接字描述符,用于与该客户端通信。
  5. 通信与关闭

    • 使用新套接字发送和接收信息。
    • 完成通信后关闭套接字。

客户端

  1. socket

    • 创建原始套接字。
  2. bind(可选)

    • 客户端可以选择是否绑定IP和端口号。
    • 如果绑定,则客户端只能以绑定的IP和端口号进行通信。通常情况下无需绑定,除非服务器要求接收特定客户端的信息。
  3. connect

    • 向服务器发送连接请求,并携带客户端的身份信息(IP和端口号)。
  4. 通信与关闭

    • 通过套接字发送和接收信息。
    • 完成通信后关闭套接字。

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,表示自动选择与domaintype兼容的协议。
  • 返回值:成功返回套接字描述符,失败返回-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;
}
代码解释:
  1. 创建套接字socket(AF_INET, SOCK_STREAM, 0) 创建一个支持 IPv4 的 TCP 套接字。
  2. 绑定 IP 和端口:通过 bind 函数将服务器的 IP 地址和端口号绑定到创建的套接字上。
  3. 监听:调用 listen 函数将套接字设置为监听状态,BACKLOG 指定了等待连接队列的最大长度。
  4. 接受客户端连接accept 函数用于从等待队列中接收客户端的连接请求,返回一个新的套接字文件描述符用于与客户端进行通信。
  5. 收发信息:使用 recv 接收客户端发来的信息,并通过 send 发送响应。消息中添加了 "5201314" 字符串后回传给客户端。
  6. 关闭套接字:完成通信后,通过 close 关闭原始套接字和客户端套接字。
注意点:
  • recvsend 用于数据传输,它们是基于 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;
}

 

代码解释:
  1. 创建套接字:客户端使用 socket 函数创建一个 TCP 套接字。
  2. 填充服务器地址结构体struct sockaddr_in 用于定义目标服务器的 IP 地址和端口号。
  3. 建立连接:客户端调用 connect 函数连接到指定服务器。如果连接成功,将输出 "成功连接到服务器"
  4. 关闭套接字:连接完成后,使用 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服务器代码示例 代码解释&…...

微服务中的技术使用与搭配:如何选择合适的工具构建高效的微服务架构

一、微服务架构中的关键技术 微服务架构涉及的技术非常广泛&#xff0c;涵盖了开发、部署、监控、安全等各个方面。以下是微服务架构中常用的一些技术及其作用&#xff1a; 1. 服务注册与发现 微服务架构的一个重要特性是各个服务是独立部署的&#xff0c;因此它们的地址&am…...

找出字符串第一个匹配项的下标

找出字符串第一个匹配项的下标 题目描述&#xff1a; 题解思路&#xff1a; 图上所示&#xff0c;利用字符滑动&#xff0c;如果匹配就字符开始移动&#xff1b;如果不匹配成功&#xff0c;则停止移动&#xff0c;并回到字符串刚开始匹配的字符下标前一个&#xff0c;为下一次…...

面向FWA市场!移远通信高性能5G-A模组RG650V-NA通过北美两大重要运营商认证

近日&#xff0c;全球领先的物联网整体解决方案供应商移远通信宣布&#xff0c;其旗下符合3GPP R17标准的新一代5G-A模组RG650V-NA成功通过了北美两家重要运营商认证。凭借高速度、大容量、低延迟、高可靠等优势&#xff0c;该模组可满足CPE、家庭/企业网关、移动热点、高清视频…...

Matlab实现北方苍鹰优化算法优化随机森林算法模型 (NGO-RF)(附源码)

目录 1.内容介绍 2.部分代码 3.实验结果 4.内容获取 1内容介绍 北方苍鹰优化算法&#xff08;Northern Goshawk Optimization, NGO&#xff09;是一种新颖的群智能优化算法&#xff0c;灵感源自北方苍鹰捕食时的策略。该算法通过模拟苍鹰的搜寻、接近和捕捉猎物的行为模式&am…...

搭建环境 配置编译运行 mpi-test-suite

1&#xff0c;编译安装 ucx 下载源码&#xff1a; $ git clone https://github.com/openucx/ucx.git $ ​git checkout v1.17.0 ​ 运行auto工具&#xff1a; $ ./autogen.sh $ ./autogen.sh 指所以运行两次是因为有时候第一次会失败&#xff0c;原因未查。 配置 ucx $ m…...

夜神模拟器启动报错:虚拟机启动失败 请进行修复 关闭hyper-v

不是关闭hyper-v的问题。 点那个没用。 解决办法&#xff1a; 我电脑win11&#xff08;win10 win11都一样 &#xff09;去安全中心-设备安全性 把内存完整性关了。 这还不够。 在右上角找系统信息 我发现VT显示没开 于是我去BIOS中开启VT 这个VT怎么开很简单。就是你F2 F1…...

投资策略规划最优决策分析

目录 一、投资策略规划问题详细 二、存在最优投资策略&#xff1a;每年都将所有钱投入到单一投资产品中 &#xff08;一&#xff09;状态转移方程 &#xff08;二&#xff09;初始条件与最优策略 &#xff08;三&#xff09;证明最优策略总是将所有钱投入到单一投资产品中…...

一篇保姆式虚拟机安装ubantu教程

前言&#xff1a; 本文将介绍在VMware安装ubantu&#xff0c;会的人可以试试上一篇介绍centos/ubantu安装docker环境,不同环境安装docker。一篇保姆式centos/unbantu安装docker 官网下载iso:Ubuntu 18.04.6 LTS (Bionic Beaver) 本次使用的版本是&#xff1a; 一&…...

缓冲区的奥秘:解析数据交错的魔法

目录 一、理解缓存区的好处 &#xff08;一&#xff09;直观性的理解 &#xff08;二&#xff09;缓存区的好处 二、经典案例分析体会 &#xff08;一&#xff09;文件读写流&#xff08;File I/O Buffering&#xff09; BufferedOutputStream 和 BufferedWriter 可以加快…...

CentOS 7.9 搭建本地Yum源

yum&#xff08;Yellow Dog Updater&#xff0c;Modified&#xff09;是一个在Fedora、Centos、RedHat中的Shell前端软件包管理器。基于RPM包管理&#xff0c;能够从指定的服务器自动下载RPM包并且安装&#xff0c;可以自动处理依赖关系&#xff0c;并且一次安装所有依赖的软件…...

【Python】爬虫实战:高效爬取电影网站信息指南(涵盖了诸多学习内容)

本期目录 1 爬取思路 2 爬虫过程 2.1 网址 2.2 查看网页代码 3 爬取数据 3.1 导入包 3.2 爬取代码 01 爬取思路 \*- 第一步&#xff0c;获取页面内容\*- 第二步&#xff1a;解析并获取单个项目链接 \*- 第三步&#xff1a;获取子页面内容 \*- 第四步&#xff1a;解析…...

MATLAB和C++及Python流式细胞术

&#x1f335;MATLAB 片段 流式细胞术&#xff08;Flow Cytometry&#xff09;是一种用于分析细胞或其他颗粒悬浮在流动介质中的方法。MATLAB 可以用来处理和分析流式细胞术的数据&#xff0c;例如用于数据预处理、可视化和分析。以下是一些常见的 MATLAB 处理流式细胞术数据的…...

Vue3 pinia使用

Pinia 是一个现代的状态管理库&#xff0c;专为 Vue 3 设计。它提供了一种简单、直观的方式来管理应用中的全局状态 (就是不同组件都希望去共享的一些变量,函数等)。Pinia 的设计灵感来自于 Vuex&#xff08;Vue 2 的状态管理库&#xff09;&#xff0c;但进行了许多改进&#…...

tdengine学习笔记-建库和建表

目录 建库和建表 创建超级表​ 创建表​ 自动建表​ 创建普通表​ 多列模型 VS 单列模型​ 数据类型映射​ 示例程序汇总​ 在车联网领域的应用 1. 数据模型概述 2. 表结构设计 2.1 静态数据表 2.2 动态数据表 4. 查询数据 4.1 查询单个车辆的数据 4.2 查询多个…...

Django数据迁移出错,解决raise NodeNotFoundError问题

错误出现在&#xff1a; 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创新与产业智能化转型

数据标注公司在人工智能领域扮演着重要角色&#xff0c;通过提供高质量的数据标注服务&#xff0c;帮助企业和组织训练和优化机器学习模型。从需求分析到数据交付&#xff0c;每一个步骤都需要严格把控&#xff0c;确保数据的质量和安全性。 景联文科技是一家专业的数据采集与标…...

MySQL学习/复习7表的内外连接

一、内连接...

Spring Cloud入门笔记2(OpenFeign)

场景&#xff1a; OpenFeign中集成了LoadBalancer,并简化了微服务调用&#xff0c;所以实际上使用该技术 技术栈&#xff1a;OpenFeign 步骤一&#xff1a;导入依赖 <!--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"…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...

Git常用命令完全指南:从入门到精通

Git常用命令完全指南&#xff1a;从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…...

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包...