【Linux】网络篇:UDP、TCP 网络接口及使用
文章目录
- socket 及 相关补充
- 0. netstat - - 查询当前服务器上网络服务器
- 1. 端口号(port)
- 2. 网络字节序
- 3. sockaddr 结构体
- 一、socket 常见 API
- UDP
- 0. IP 地址转化 函数
- 1. socket 函数:创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)
- 2. bind 函数:绑定端口号 (TCP/UDP, 服务器)
- 3. recvfrom 函数:接收来自socket的信息
- 4. sendto 函数:发送信息给socket
- TCP
- 1. listen 函数:开始监听socket (TCP, 服务器)
- 2. accept 函数:接收连接请求 (TCP, 服务器)
- 3. read 函数:读取文件(网络)中的内容
- 4. write 函数:写入数据到文件(网络)
- 5. connect 函数:发起链接请求 (TCP, 客户端)
- 6. recv 函数:接收来自套接字的信息
socket 及 相关补充
Socket 是一种通信机制,通过它可以在不同主机之间进行数据交换。
-
在Socket 编程中,有两种常见的通信模式:客户端-服务器模式 和 点对点模式。
-
它基于 TCP/IP 协议栈,并使用 IP地址 和 端口号 来标识通信的目标。
-
Socket 编程可以通过 TCP(传输控制协议) 和 UDP(用户数据报协议) 实现不同类型的连接。
-
socket 接口 创建的是文件,不同主机通过这个接口进行通信,即 网络通信依附的也是文件系统
0. netstat - - 查询当前服务器上网络服务器
netstat -naup:
-n:把相应信息显示成数字
-a:显示所有进程
-u:显示 upd
-p:显示 进程
netstat -nltp:
-n:把相应信息显示成数字
-l:显示状态为监听 listen 的进程
-t:显示 tcp
-p:显示 进程
1. 端口号(port)
端口号是传输层协议的内容
-
数据类型为
uint16_t,即 16 位的 2 字节整数 -
一个端口号只能标识一个进程,告诉操作系统,当前的这个数据要交给哪一个进程来处理
-
IP地址 + 端口号,就能够标识网络上的某一台主机的某一个进程
注意:进程 pid 是唯一表示的,端口号也是唯一表示的,没有必然关系,就好比身份证和工号自己标记自己的
2. 网络字节序
讨论网络字节序还是主机字节序的意义,保证了主机能正确收发数据信息
发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出,这需要接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存。
网络数据流的地址这样规定:先发出的数据是低地址,后发出的数据是高地址。
- TCP/IP 协议规定,网络数据流应采用大端字节序,即低地址高字节。
- 不管这台主机是大端机还是小端机,都会按照这个 TCP/IP 规定的网络字节序来发送/接收数据。
- 如果当前发送主机是小端,就需要先将数据转成大端;否则就忽略,直接发送即可。
网络字节序和主机字节序的转换:
#include <arpa/inet.h>uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohl(uint16_t hostshort);
-
h 表示 host,n 表示 network,l 表示 32 位长整数,s 表示 16 位短整数。
-
接收和发送端口号,用这些接口转化
例如:htonl 表示将 32 位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送。
如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回;
如果主机是大端字节序,这些函数不做转换,将参数原封不动地返回。
3. sockaddr 结构体
是用于储存网络地址信息的结构体,实现了多态。
IPv4 和 IPv6 的地址格式定义在 头文件 netinet/in.h 中
IPv4 地址用 sockaddr_in 结构体表示,包括:
- 16 位地址类型
- 16 位端口号和
- 32 位 IP 地址
/* Structure describing an Internet socket address. */
struct sockaddr_in
{__SOCKADDR_COMMON (sin_); /*16位地址类型*/in_port_t sin_port; /* Port number.端口号,无符号16位整数*/struct in_addr sin_addr; /* Internet address.IP 地址,无符号32位整数*//* Pad to size of `struct sockaddr'. */unsigned char sin_zero[sizeof (struct sockaddr) -__SOCKADDR_COMMON_SIZE -sizeof (in_port_t) -sizeof (struct in_addr)];};/* This macro is used to declare the initial common membersof the data types used for socket addresses, `struct sockaddr',`struct sockaddr_in', `struct sockaddr_un', etc. */#define __SOCKADDR_COMMON(sa_prefix) \sa_family_t sa_prefix##family
-
IPv4 地址类型 定义为常数 AF_INET
-
IPv6 地址类型 定义为常数 AF_INET6
这样,只要取得某种 sockaddr 结构体的首地址不需要知道具体是哪种类型的 sockaddr 结构体,就可以根据地址类型字段确定结构体中的内容。
- socket API 可以都用 struct sockaddr * 类型表示,在使用的时候需要强制转化成 sockaddr_in
这样的好处是程序的通用性,可以接收 IPv4、IPv6、以及 UNIX Domain Socket 各种类型的 sockaddr 结构体指针做为参数
一、socket 常见 API
UDP
0. IP 地址转化 函数
// 字符串风格的 IP 地址,转换成为 4 字节 int,同时将主机序列转化成为网络序列
in_addr_t inet_addr(const char *cp);// 4 字节 int,转化为字符串风格 IP 地址
char *inet_ntoa(struct in_addr in);// string 类型 IP 地址,转换成网络序列的 4 字节 IP 地址
// &struct sockaddr.sin_addr(点的优先级高)
int inet_aton(const char *cp, struct in_addr *inp);
1. socket 函数:创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)
#include <sys/types.h>
#include <sys/socket.h>
网络通信依附的也是文件系统!创建的是文件描述符。
int socket(int domain, int type, int protocol);参数 domian(地址类型,即选择通信方式):
- AF_INET,IPv4 网络通信
- AF_INET6,IPv6 网络通信
- AF_UNIX,本地通信
参数 type:
- SOCK_STREAM,流式套接(TCP)
- SOCK_DGRAM,用户数据报(支持无连接、不可靠的数据通信,UDP)
参数 protocol:
- 默认设为 0,就可以自动识别是 TCP 还是 UDP
返回值:
- 创建成功返回文件描述符,创建失败返回 -1,并设置错误码
2. bind 函数:绑定端口号 (TCP/UDP, 服务器)
比如我们在实现某个函数时对 socket 进行了填充,可是创建的都是临时变量,于是就需要使用 bind 对填充数据进行于 socket 的绑定
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int bind(int socket, const struct sockaddr *address, socklen_t address_len);参数 socket:
- 套接字的文件描述符
参数 address:
- 用户自定义的用于填充数据的结构体,需要强转成 (struct sockaddr*) 使用
参数 address_len:
- 实际传入 address 的大小,即 sizeof(address)
返回值:
- 成功返回 0 ,失败返回 -1
3. recvfrom 函数:接收来自socket的信息
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);参数 sockfd:
- 服务端所绑定的套接字,后续接收和访问都从这里来
参数 buf:
- 未来读到的数据要放在哪一个用户或者缓冲区里
参数 len:
- 缓冲区的长度
参数 flags:
- 0,默认以阻塞方式读取
参数 src_addr:
- 接收缓冲区,获取到客户端的 IP 和 端口号,需要强转成 (struct sockaddr*) 使用
参数 addrlen:
- 接收缓冲区的大小的地址
返回值:
- 成功则返回接收的字节数,失败返回 -1 并设置错误码
4. sendto 函数:发送信息给socket
#include <sys/types.h>
#include <sys/socket.h>
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);参数 sockfd:
- 服务端所绑定的套接字,后续接收和访问都从这里来
参数 buf:
- 未来发送的数据是哪一个用户或者缓冲区里的
参数 len:
- 缓冲区的长度
参数 flags:
- 0,默认以阻塞方式调用
参数 dest_addr:
- 发送缓冲区,需要发送到哪一个客户端,需要强转成 (struct sockaddr*) 使用
参数 addrlen:
- 接收缓冲区的大小
返回值:
- 成功则返回发送的字节数,失败返回 -1 并设置错误码
TCP
1. listen 函数:开始监听socket (TCP, 服务器)
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int listen(int sockfd, int backlog);参数 sockfd:
- 监听的套接字的文件描述符
参数 backlog:
- 一个整数
返回值:
- 成功返回 0,失败返回 -1,并设置错误码
2. accept 函数:接收连接请求 (TCP, 服务器)
#include <sys/types.h>
#include <sys/socket.h>
int accept(int socket, struct sockaddr* address, socklen_t* address_len);参数 socket:
- 监听套接字的文件描述符
参数 address:
- 接收缓冲区,获取到客户端的 IP 和 端口号,需要强转成 (struct sockaddr*) 使用
参数 address_len:
- 接收缓冲区的大小的地址
返回值:
- 如果接收成功,返回一个文件描述符(这一个套接字是完成具体业务的),接收失败则返回 -1,并设置错误码
3. read 函数:读取文件(网络)中的内容
ps:tcp 是面向流的,可以用;udp 是面向数据报的,不可以用
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);返回值:
- 成功返回读取到的字符数,对方关闭连接返回 0,读取失败返回 -1,并设置错误码
4. write 函数:写入数据到文件(网络)
ps:tcp 是面向流的,可以用;udp 是面向数据报的,不可以用
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);返回值:
- 成功返回写入的字符数,写入失败返回 -1,并设置错误码
5. connect 函数:发起链接请求 (TCP, 客户端)
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);参数 sockfd:
- 发起连接的套接字的文件描述符
参数 addr:
- 记录要发送对象的信息缓冲区,转成 (struct sockaddr *) 可以使用
参数 addrlen:
- 缓冲区的大小
返回值:
- 成功返回 0,失败返回 -1,并设置错误码
6. recv 函数:接收来自套接字的信息
使用和 read 几乎一样。
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags);参数 sockfd:
- 服务端所绑定的套接字,后续接收和访问都从这里来
参数 buf:
- 未来读到的数据要放在哪一个用户或者缓冲区里
参数 len:
- 缓冲区的长度
参数 flags:
- 0,默认以阻塞方式读取
返回值:
- 成功则返回接收的字节数,失败返回 -1 并设置错误码
相关文章:
【Linux】网络篇:UDP、TCP 网络接口及使用
文章目录 socket 及 相关补充0. netstat - - 查询当前服务器上网络服务器1. 端口号(port)2. 网络字节序3. sockaddr 结构体 一、socket 常见 APIUDP0. IP 地址转化 函数1. socket 函数:创建 socket 文件描述符 (TCP/UDP, 客户端 服务器)2. b…...
卡尔曼滤波(Kalman Filter)原理浅析-数学理论推导-2
目录 前言数学理论推导卡尔曼增益超详细数学推导结语参考 前言 最近项目需求涉及到目标跟踪部分,准备从 DeepSORT 多目标跟踪算法入手。DeepSORT 中涉及的内容有点多,以前也就对其进行了简单的了解,但是真正去做发现总是存在这样或者那样的困…...
SQL 性能优化总结
文章目录 一、性能优化策略二、索引创建规则三、查询优化总结 一、性能优化策略 1. SQL 语句中 IN 包含的值不应过多 MySQL 将 IN中的常量全部存储在一个排好序的数组里面,但是如果数值较多,产生的消耗也是比较大的。所以对于连续的数值,能用…...
MYSQL事务隔离级别分析
MYSQL事务隔离级别分析 不可重复读和幻读的区别? 不可重复读和幻读的区别? 先理解几个概念 不可重复读 一个事务中,后续查询结果得到不同的数据,可被重复读隔离级别解决幻影 出现在查询结果集中但不出现在较早查询的结果集中的行幻…...
学习javaEE初阶的第一堂课
学习金字塔 java发展简史 Java最初诞生的时候是用来写前端的!! 199x年 199x年,互联网还处在比较早期的阶段,当时主流的编程语言是 C/C, 有个大佬要搞个"智能面包机",觉得用C来做太难了 于是就基于C搞了个简单点的语言,Java 就诞生了~~ 遗憾的是项目流产了,没做成…...
请问一下就是业务概念模型和业务逻辑模型有啥关系
请问一下就是业务概念模型和业务逻辑模型有啥关系? 业务概念模型和业务逻辑模型是业务建模的两个关键组成部分,两者密切相关但又有所不同。 1.业务概念模型:这是对业务术语、定义和关系的一种抽象表示。它是从业务专家那里获得的知识&#…...
3.2 Android eBPF程序类型
写在前面 为什么要先了解eBPF程序类型? 从帮助函数中,我们可能基于内核的eBPF开放API,对eBPF的能力有一个比较细致的认识,但是这并不能让我们从全局,或者更概括的认识eBPF。eBPF程序类型能够更宏观的告诉我们,eBPF能做哪些事情(除网络相关)。 一,eBPF程序类型 内核…...
多目标优化算法:基于非支配排序的小龙虾优化算法(NSCOA)MATLAB
一、小龙虾优化算法COA 小龙虾优化算法(Crayfsh optimization algorithm,COA)由Jia Heming 等人于2023年提出,该算法模拟小龙虾的避暑、竞争和觅食行为,具有搜索速度快,搜索能力强,能够有效平衡…...
Linux学习第13天:嵌入式LinuxLED驱动开发:一字一符总见情
在正式写这篇笔记前,有一个事情必须要说一下。昨天更新的基于API函数的字符设备驱动开发按照正常的教程来说应该在本笔记后一天更新才对。但是由于我一时的疏忽,跳过了本笔记。在昨天学习基于API函数的时候造成了一定程度的困扰。今天重翻教程的时候才发…...
ModuleNotFoundError: No module named ‘omni‘
install isaac sim on linux open the isaac sim folder in /home//.local/share/ov/pkg/isaac_sim-2022.1.1 source setup_python_env.sh ./python.sh standalone_examples/replicator/offline_generation.pyNo module named ‘omni.isaac’...
题解:ABC320B - Longest Palindrome
题解:ABC320B - Longest Palindrome 题目 链接:Atcoder。 链接:洛谷。 难度 算法难度:C。 思维难度:C。 调码难度:C。 综合评价:入门。 算法 字符串处理。 思路 通过双层循环分别枚…...
大模型从入门到应用——LangChain:代理(Agents)-[代理执行器(Agent Executor):结合使用Agent和VectorStore]
分类目录:《大模型从入门到应用》总目录 代理执行器接受一个代理和工具,并使用代理来决定调用哪些工具以及以何种顺序调用。本文将参数如何结合使用Agent和VectorStore。这种用法是将数据加载到VectorStore中,并希望以Agent的方式与之进行交互…...
【算法题】100040. 让所有学生保持开心的分组方法数
题目: 给你一个下标从 0 开始、长度为 n 的整数数组 nums ,其中 n 是班级中学生的总数。班主任希望能够在让所有学生保持开心的情况下选出一组学生: 如果能够满足下述两个条件之一,则认为第 i 位学生将会保持开心: …...
TrOCR – 基于 Transformer 的 OCR 入门
一、TrOCR 架构 近些年,光学字符识别 (OCR) 出现了多项创新。它对零售、医疗保健、银行和许多其他行业的影响是巨大的。与深度学习的许多其他领域一样,OCR领域也看到了Transformer 神经网络的重要性和影响。如今,出现了像TrOCR(Transformer OCR)这样的模型,它在准确性方面…...
单例模式优缺点
单例模式是一种创建型设计模式,其主要目的是确保类只有一个实例,并提供全局访问点来获取该实例。单例模式具有一些优点和缺点,下面我将列出它们: **优点:** 1. **全局唯一性**:单例模式确保在应用程序中只…...
【Java 基础篇】Java 字节流详解:从入门到精通
Java中的字节流是处理二进制数据的关键工具之一。无论是文件操作、网络通信还是数据处理,字节流都发挥着重要作用。本文将从基础概念开始,深入探讨Java字节流的使用,旨在帮助初学者理解和掌握这一重要主题。 什么是字节流? 在Ja…...
Vue记录(下篇)
Vuex getters配置项 *Count.vue <template><div><h1>当前求和为:{{$store.state.sum}}</h1><h3>当前求和的10倍为:{{$store.getters.bigSum}}</h3><select v-model.number"n"><option value&q…...
【测试开发】概念篇 · 测试相关基础概念 · 常见开发模型 · 常见测试模型
【测试开发】概念篇 文章目录 【测试开发】概念篇1. 什么是需求1.1 需求的定义1.2 为什么有需求1.3 测试人员眼里的需求1.4 如何深入了解需求 2. 什么是测试用例2.1 为什么有测试用例2.2 练习>手机打电话 3. 什么是bug4. 开发模型和测试模型4.1 软件生命周期4.2 开发模型4.3…...
1. 快速体验 VSCode 和 CMake 创建 C/C++项目
1. 快速体验 VSCode 和 CMake 创建 C/C项目 本章的全部代码和markdown文件地址: CMake_Tutorial,欢迎互相交流. 此次介绍的内容都是针对于 Linux 操作系统上的开发过程. 1.1 安装开发工具 VSCode: 自行下载安装, 然后安装插件 Cmake:在 Ubuntu 系统上, 可以采用 ap…...
【JAVA-Day18】用大白话讲解 Java 中的内存机制
标题 用大白话讲解 Java 中的内存机制摘要引言一、Java 内存机制1.1 栈内存1.2 堆内存 二、Java 如何管理内存三、合理管理内存的必要性与其他方式相比优势劣势建议四、总结参考资料 博主 默语带您 Go to New World. ✍ 个人主页—— 默语 的博客👦🏻 《…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...
FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...
脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...
