嵌入式养成计划-29-网络编程----TCP与UDP的基础模型

Linux下,基于TCP与UDP协议,不同进程下单线程通信服务器

Linux下,基于TCP与UDP协议,不同进程下单线程通信服务器

六十五、TCP与UDP的基础模型

1. socket

1.1 套接字概念

  • 最早的套接字和共享内存,消息队列,管道一样,只能实现一个主机内部的进程间通信。
  • 后期加入了TCP/IP协议,使的套接字能够支持不同主机之间的进程间通信。
  • socket函数,可以在内核空间中创建两块缓冲区,供于发送数据,接收数据。
    在这里插入图片描述

1.2 socket 函数

功能:在内核空间中创建两个缓冲区(发送缓冲区,接收缓冲区),返回该缓冲区的文件描述符到用户空间中;
原型:#include <sys/types.h>          /* See NOTES */#include <sys/socket.h>int socket(int domain, int type, int protocol);
参数:int domain:地址族,协议族。Name                Purpose                          Man pageAF_UNIX, AF_LOCAL   Local communication              unix(7)AF_INET             IPv4 Internet protocols          ip(7)AF_INET6            IPv6 Internet protocols          ipv6(7)int type:  SOCK_STREAM:字节流式套接字,流式套接字,默认使用TCP协议;SOCK_DGRAM:  数据报式套接字,报式套接字,默认使用UDP协议;SOCK_RAW:    原始套接字,协议需要在第三个参数手动指定.int protocol:默认协议,填0;IPPROTO_TCP  IPPROTO_UDP  IPPROTO_IP
返回值:成功,返回一个新的文件描述符;失败,返回-1,更新errno;

2. TCP编程

2.1 TCP流程图

在这里插入图片描述

2.2 TCP 中的函数

2.2.1 socket

功能:在内核空间中创建两个缓冲区(发送缓冲区,接收缓冲区),返回该缓冲区的文件描述符到用户空间中;
原型:#include <sys/types.h>          /* See NOTES */#include <sys/socket.h>int socket(int domain, int type, int protocol);
参数:int domain:地址族,协议族。Name                Purpose                          Man pageAF_UNIX, AF_LOCAL   Local communication              unix(7)AF_INET             IPv4 Internet protocols          ip(7)AF_INET6            IPv6 Internet protocols          ipv6(7)int type:  SOCK_STREAM:字节流式套接字,流式套接字,默认使用TCP协议;SOCK_DGRAM:  数据报式套接字,报式套接字,默认使用UDP协议;SOCK_RAW:    原始套接字,协议需要在第三个参数手动指定.int protocol:默认协议,填0;IPPROTO_TCP  IPPROTO_UDP  IPPROTO_IP
返回值:成功,返回一个新的文件描述符;失败,返回-1,更新errno;

2.2.2 bind

功能:绑定地址信息到指定套接字上;
原型:#include <sys/types.h>          /* See NOTES */#include <sys/socket.h>int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
参数:int sockfd:指定要绑定到哪个套接字上,填对应的文件描述符;struct sockaddr *addr:通用地址信息结构体,真实的地址信息结构体根据地址族指定。手动填充上地址信息(例如:IP和端口),给bind函数绑定使用;AF_INET: man 7 IPstruct sockaddr_in {sa_family_t    sin_family; /* address family: AF_INET */     必须填AF_INETin_port_t      sin_port;   /* port in network byte order */  端口号的网络字节序(1024~49151struct in_addr sin_addr;   /* internet address */      IP地址的网络字节序,(本机IP:ifconfig查看)       };/* Internet address. */struct in_addr {uint32_t       s_addr;     /* address in network byte order */};AF_INET6: man 7 ipv6          socklen_t addrlen:真实的地址信息结构体的大小,sizeof(struct sockaddr_in);
返回值:成功,返回0;失败,返回-1,更新errno;

报错解释:bind: Address already in use ---->原因:代码异常退出后,端口号会在30s~3min不等的时间释放。

2.2.3 listen

功能:将套接字设置为被动监听状态;让内核去维护两个队列:未完成连接的队列,已完成连接的队列
原型:#include <sys/types.h>          /* See NOTES */#include <sys/socket.h>int listen(int sockfd, int backlog);
参数:int sockfd:指定要转换成被动监听状态的文件描述符;int backlog:指定未完成连接队列的容量,不要填01即可,一般填128;
返回值:成功,返回0;失败,返回-1,更新errno;

2.2.4 accept(阻塞函数)

功能:阻塞函数,阻塞等待客户端连接成功,从已完成连接的队列中获取一个客户端信息,生成一个新的文件描述符。该文件描述符才是与客户端通信的文件描述符;
原型:#include <sys/types.h>          /* See NOTES */#include <sys/socket.h>int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数:int sockfd:被转换成被动监听状态的文件描述符;struct sockaddr *addr:通用地址信息结构体,真实的地址信息结构体根据地址族指定。存储获取到的客户端的地址信息;若不想获取,则填NULL;AF_INET: man 7 IPstruct sockaddr_in {sa_family_t    sin_family; /* address family: AF_INET */     必须填AF_INETin_port_t      sin_port;   /* port in network byte order */  端口号的网络字节序(1024~49151struct in_addr sin_addr;   /* internet address */      IP地址的网络字节序,(本机IP:ifconfig查看)       };/* Internet address. */struct in_addr {uint32_t       s_addr;     /* address in network byte order */};   socklen_t *addrlen:真实的地址信息结构体的大小,注意是指针类型,若第二个参数填NULL,则该参数也填NULL;  
返回值:成功,返回新的通信套接字文件描述符; 该文件描述符才是与客户端通信的文件描述符;失败,返回-1,更新errno;

2.2.5 recv

功能:接收数据;
原型:#include <sys/types.h>#include <sys/socket.h>ssize_t recv(int sockfd, void *buf, size_t len, int flags);
参数:int sockfd:指定从哪个套接字维护的缓冲区中读取数据;void *buf:存储接收到的数据,void*:可以接收任意类型数据;size_t len:指定要接收多少个字节的数据;int flags:0:阻塞方式,当缓冲区中没有数据的时候,该函数阻塞; 若flags==0, 则recv函数等价于read函数;MSG_DONTWAIT:非阻塞方式,当当缓冲区中没有数据的时候,该函数不阻塞;且函数运行失败;
返回值:>0, 成功读取到的字节数;=0,在流失套接字中,若对端关闭,则返回0;=-1, 函数运行失败,更新errno;recv(sockfd, buf, len, flags);等价于 recvfrom(sockfd, buf, len, flags, NULL, NULL);
  • recv函数能否替换成其他函数?
    可以,当recv函数最后一个参数填0,可以替换成read函数,
    当recvfrom后面两个参数填NULL的时候,等价于recv函数,所以可以替换成recvfrom

2.2.6 send

功能:发送数据;
原型:#include <sys/types.h>#include <sys/socket.h>ssize_t send(int sockfd, const void *buf, size_t len, int flags);
参数:int sockfd:指定向哪个套接字维护的缓冲区中写入数据;void *buf:指定要发送的数据的首地址,void*:可以发送任意类型数据;size_t len:指定要发送多少个字节的数据;int flags:0:阻塞方式,当缓冲区中满的时候,该函数阻塞; 若flags==0, 则send函数等价于write函数;MSG_DONTWAIT:非阻塞方式,当缓冲区中满的时候,该函数不阻塞;且函数运行失败;    
返回值:>0, 成功发送的字节数;=-1,函数运行失败,更新errno;send(sockfd, buf, len, flags);等价于 sendto(sockfd, buf, len, flags, NULL, 0);
  • send函数能否替换成其他函数?
    可以,当send函数最后一个参数填0,可以替换成write函数,
    当sendto后面两个参数填NULL, 0 的时候,等价于send函数,所以可以替换成sendto

2.2.7 connect

功能:连接服务器;
原型:#include <sys/types.h>          /* See NOTES */#include <sys/socket.h>int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
参数:int sockfd:指定要通过哪个文件描述符连接服务器;struct sockaddr *addr:通用地址信息结构体,真实的地址信息结构体根据地址族指定。手动填充上服务器的地址信息(例如:IP和端口),给connect函数绑定使用; 想要连接哪个服务器就填哪个服务器的地址信息AF_INET: man 7 IPstruct sockaddr_in {sa_family_t    sin_family; /* address family: AF_INET */     必须填AF_INETin_port_t      sin_port;   /* port in network byte order */  端口号的网络字节序(1024~49151struct in_addr sin_addr;   /* internet address */      IP地址的网络字节序,(本机IP:ifconfig查看)       };/* Internet address. */struct in_addr {uint32_t       s_addr;     /* address in network byte order */};socklen_t addrlen:真实的地址信息结构体的大小,sizeof(struct sockaddr_in);
返回值:成功,返回0;失败,返回-1,更新errno;

3. UDP编程

3.1 UDP流程图

在这里插入图片描述

3.2 UDP搭建

3.2.1 socket

功能:在内核空间中创建两个缓冲区(发送缓冲区,接收缓冲区),返回该缓冲区的文件描述符到用户空间中;
原型:#include <sys/types.h>          /* See NOTES */#include <sys/socket.h>int socket(int domain, int type, int protocol);
参数:int domain:地址族,协议族。Name                Purpose                          Man pageAF_UNIX, AF_LOCAL   Local communication              unix(7)AF_INET             IPv4 Internet protocols          ip(7)AF_INET6            IPv6 Internet protocols          ipv6(7)int type:  SOCK_STREAM:字节流式套接字,流式套接字,默认使用TCP协议;SOCK_DGRAM:  数据报式套接字,报式套接字,默认使用UDP协议;SOCK_RAW:    原始套接字,协议需要在第三个参数手动指定.int protocol:默认协议,填0;IPPROTO_TCP  IPPROTO_UDP  IPPROTO_IP
返回值:成功,返回一个新的文件描述符;失败,返回-1,更新errno;

3.2.2 bind

功能:绑定地址信息到指定套接字上;
原型:#include <sys/types.h>          /* See NOTES */#include <sys/socket.h>int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
参数:int sockfd:指定要绑定到哪个套接字上,填对应的文件描述符;struct sockaddr *addr:通用地址信息结构体,真实的地址信息结构体根据地址族指定。手动填充上地址信息(例如:IP和端口),给bind函数绑定使用;AF_INET: man 7 IPstruct sockaddr_in {sa_family_t    sin_family; /* address family: AF_INET */     必须填AF_INETin_port_t      sin_port;   /* port in network byte order */  端口号的网络字节序(1024~49151struct in_addr sin_addr;   /* internet address */      IP地址的网络字节序,(本机IP:ifconfig查看)       };/* Internet address. */struct in_addr {uint32_t       s_addr;     /* address in network byte order */};AF_INET6: man 7 ipv6          socklen_t addrlen:真实的地址信息结构体的大小,sizeof(struct sockaddr_in);
返回值:成功,返回0;失败,返回-1,更新errno;

3.2.3 recvfrom

功能:接收数据的同时可以获取到该数据包从哪里来,即可以知道发送方的地址信息;
原型:#include <sys/types.h>#include <sys/socket.h>ssize_t recv(int sockfd, void *buf, size_t len, int flags);ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
参数:int sockfd:指定从哪个套接字维护的缓冲区中读取数据;void *buf:存储接收到的数据,void*:可以接收任意类型数据;size_t len:指定要接收多少个字节的数据;int flags:0:阻塞方式,当缓冲区中没有数据的时候,该函数阻塞; 若flags==0, 则recv函数等价于read函数;MSG_DONTWAIT:非阻塞方式,当当缓冲区中没有数据的时候,该函数不阻塞;且函数运行失败;struct sockaddr *src_addr:通用地址信息结构体,真实的地址信息结构体根据地址族指定。用于存储发送方的地址信息的,即用于存储这个包是从谁那里发送过来的。若不想接收则填NULL;AF_INET: man 7 IPstruct sockaddr_in {sa_family_t    sin_family; /* address family: AF_INET */     必须填AF_INETin_port_t      sin_port;   /* port in network byte order */  端口号的网络字节序(1024~49151struct in_addr sin_addr;   /* internet address */      IP地址的网络字节序,(本机IP:ifconfig查看)       };/* Internet address. */struct in_addr {uint32_t       s_addr;     /* address in network byte order */};   socklen_t *addrlen:真实的地址信息结构体的大小,注意是指针类型,若第二个参数填NULL,则该参数也填NULL;  
返回值:>0, 成功读取到的字节数;=0,但是只有在流失套接字中,若对端关闭,则返回0;=-1, 函数运行失败,更新errno;

recv(sockfd, buf, len, flags);
等价于 recvfrom(sockfd, buf, len, flags, NULL, NULL);

3.2.4 sendto

功能:发送数据给指定该数据包应该发给谁,即指定接收方的地址,必须指定清楚这个包该发给谁
原型:#include <sys/types.h>#include <sys/socket.h>ssize_t send(int sockfd, const void *buf, size_t len, int flags);ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
参数:int sockfd:指定向哪个套接字维护的缓冲区中写入数据;void *buf:指定要发送的数据的首地址,void*:可以发送任意类型数据;size_t len:指定要发送多少个字节的数据;int flags:0:阻塞方式,当缓冲区中满的时候,该函数阻塞; 若flags==0, 则send函数等价于write函数;MSG_DONTWAIT:非阻塞方式,当缓冲区中满的时候,该函数不阻塞;且函数运行失败;  struct sockaddr *src_addr:通用地址信息结构体,真实的地址信息结构体根据地址族指定。指定该数据包应该发给谁,即指定接收方的地址信息,想发给谁填谁的地址信息;AF_INET: man 7 IPstruct sockaddr_in {sa_family_t    sin_family; /* address family: AF_INET */     必须填AF_INETin_port_t      sin_port;   /* port in network byte order */  端口号的网络字节序(1024~49151struct in_addr sin_addr;   /* internet address */      IP地址的网络字节序,(本机IP:ifconfig查看)       };/* Internet address. */struct in_addr {uint32_t       s_addr;     /* address in network byte order */};   socklen_t addrlen:真实的地址信息结构体的大小;              
返回值:>0, 成功发送的字节数;=-1,函数运行失败,更新errno; 

send(sockfd, buf, len, flags);
等价于 sendto(sockfd, buf, len, flags, NULL, 0);

网络调试工具— —飞机的用法

  • 注意: 关闭计算机的杀毒软件,电脑管家,防火墙

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/82754.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一篇文章带你学会Hadoop-3.3.4集群部署

目录 ​编辑 一、Hadoop集群部署 二、基础设施配置 2.1 设置网络 2.1.1 设置主机名称 2.1.2 设置hosts配置文件 2.1.3 关闭防火墙 2.1.4 关闭selinux 2.1.5 更换语言环境 2.1.6 更换时区 2.1.7 ssh免密 2.1.7.1 生成.ssh文件夹 2.1.7.2 进入文件夹 2.1.7.3 生成密码和…

MySQL数据库查缺补漏——基础篇

MySQL数据库查缺补漏-基础篇 基础篇 net start mysql80[服务名] net stop mysql80 create database pshdhx default charset utf8mb4; 为什么不使用utf8&#xff1f;因为其字符占用三个字节&#xff0c;有四个字节的字符&#xff0c;所有需要设置为utf8mb4; 数值类型&…

Windows10/11无线网卡WIFI驱动详细下载安装教程

官网下载WIFI驱动 《intel官网》 找到下载Windows 10 and Windows 11* WiFi package drivers 查看详细信息 下载对应操作系统的WIFI驱动 安装驱动&#xff0c;然后重启电脑即可。

【操作系统】聊聊文件系统是如何工作的

文件系统其实是操作系统中存储的核心、计算、网络。除了使用寄存器、内存可以临时存储数据&#xff0c;使用磁盘持久化存储更重要。 磁盘为系统提供了数据持久化功能。文件系统在磁盘的基础上&#xff0c;抽象出了一个管理文件的树状结构 索引节点和目录项 Linux中一切皆是文…

HarmonyOS应用开发—资源分类与访问

应用开发过程中&#xff0c;经常需要用到颜色、字体、间距、图片等资源&#xff0c;在不同的设备或配置中&#xff0c;这些资源的值可能不同。 应用资源&#xff1a;借助资源文件能力&#xff0c;开发者在应用中自定义资源&#xff0c;自行管理这些资源在不同的设备或配置中的表…

7.4.4 【MySQL】索引字符串值的前缀

我们知道一个字符串其实是由若干个字符组成&#xff0c;如果我们在 MySQL 中使用 utf8 字符集去存储字符串的话&#xff0c;编码一个字符需要占用 1~3 个字节。假设我们的字符串很长&#xff0c;那存储一个字符串就需要占用很大的存储空间。在我们需要为这个字符串列建立索引时…

一键集成prometheus监控微服务接口平均响应时长

一、效果展示 二、环境准备 prometheus + grafana环境 参考博文:https://blog.csdn.net/luckywuxn/article/details/129475991 三、导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter

UE5学习笔记(1)——从源码开始编译安装UE5

目录 0. 前期准备1. Git bash here2. 克隆官方源码。3. 选择安装分支4. 运行Setup.bat&#xff0c;下载依赖文件5. 运行GenerateProjectFiles.bat生成工程文件6. 生成完成&#xff0c;找到UE5.sln/UE4.sln7. 大功告成 0. 前期准备 0.1 在windows的话&#xff0c;建议装一个Git…

Markdown(MD)——Typora Markdown安装教程(2023九月亲测可用!!!)

目录 一、简介 1.Markdown简介 2.Markdown特点 3.Typora简介 二、安装教程 1.下载安装包 2.解压到文件夹 3.安装 4.破解 ​编辑5.激活 三、Markdown常用语法 1.常用语法 2.用于编辑LaTex公式 四、其他编辑器 一、简介 1.Markdown简介 Markdown 是一种轻量级标记语…

WPF——Control与Template理解

文章目录 一、前言二、控件三、模板3.1 DataTemplate3.2 ControlTemplate3.3 ContentPresenter 四、结语 一、前言 最近又翻看了下刘铁猛的《深入浅出WPF》&#xff0c;发现对模板章节中的部分内容有了更深的体会&#xff0c;所以写篇文扯扯。 文章标题是Control与Template&a…

企业级数据仓库-理论知识

D3 AM 大数据中间件 Hive&#xff1a;将SQL转化成分布式Map/Reduce进行运算&#xff0c;也支持转换成Spark,需要单独安装Hive集群才能访问Spark,支持60%的SQL&#xff0c;延迟比较大。SparkSQL:属于Spark生态圈&#xff0c;Hive on Sqark。HBase: NoSQL,高并发读&#xff0c;适…

c语言进阶部分详解(指针进阶1)

大家好&#xff01;指针的初阶内容我已经写好&#xff0c;可移步至我的文章&#xff1a;c语言进阶部分详解&#xff08;指针初阶&#xff09;_总之就是非常唔姆的博客-CSDN博客 基本内容我便不再赘述&#xff0c;直接带大家进入进阶内容&#xff1a; 目录 一.字符指针 1.讲解…

Mac 安装软件各种报错解决方案

Mac 安装软件各种报错解决方案 文章目录 Mac 安装软件各种报错解决方案一. 打开允许“允许任何来源”二. 无法打开"xxx"&#xff0c;因为它不是从App Store下载三. 无法打开"xxx"&#xff0c;因为 Apple无法检查其是否包含恶意软件。四. "xxx"已…

【入门篇】ClickHouse最优秀的开源列式存储数据库

文章目录 一、什么是ClickHouse&#xff1f;OLAP场景的关键特征列式数据库更适合OLAP场景的原因输入/输出CPU 1.1 ClickHouse的定义与发展历程1.2 ClickHouse的版本介绍 二、ClickHouse的主要特性2.1 高性能的列式存储2.2 实时的分析查询2.3 高度可扩展性2.4 数据压缩2.5 SQL支…

C语言——通讯录管理系统

通讯录管理系统项目简介 功能说明 控制台黑窗口实现程序需要满足以下几个功能 程序开始运行时首先显示选择菜单界面&#xff0c;根据用户输入确定实现何种功能 程序界面 代码实现 多文件实现 和之前写的实战项目类似&#xff0c;这里同样采用多文件实现的方式 多文件写代码…

各种电机驱动原理

步进电机 步进电机参考资料 野火官方文档 步进电机驱动原理 上面参考文档中有的内容就不写了&#xff0c;写一下我自己的总结吧。 说明&#xff1a; 电机驱动器输入信号有电机转动方向信号DIR&#xff0c;电机转速信号PWM&#xff0c;电机使能信号EN&#xff1b;电机驱动器…

S7-1200PLC和LED电子看板通信(TCP/IP)

S7-200SMART PLC和LED电子看板通信应用,请查看下面文章链接: SMART 200 PLC UDP通讯应用LED看板_RXXW_Dor的博客-CSDN博客开放式用户通信 (OUC) 库:数据解析:https://rxxw-control.blog.csdn.net/article/details/121424897这篇博客我们主要介绍S7-1200PLC和LED电子看板通…

servlet 引用src目录下子目录的class文件方法

1、MyServlet class文件所处的目录结构如下&#xff1a; 2、如果在url里直接引用是不行的&#xff0c;http://localhost:9092/GetRequest_Web_exploded/MyServlet 3、需要在web.xml映射后才行&#xff1a; MyServlet com.example.MyServlet <servlet-mapping><ser…

HI_NAS linux 记录

dev/root 100% 占用解决记录 通过下面的命令查看各文件夹 大小 sudo du --max-depth1 -h # 统计当前文件夹下各个文件夹的大小显示为M 最终发现Var/log 占用很大空间 发现下面两个 log 占用空间很大&#xff0c;直接 rm-rf 即可 HI NAS python3 记录 # 安装pip3 sudo apt u…

Linux下C语言使用 netlink sockets与内核模块通信

netlink简介 Netlink套接字是用以实现用户进程与内核进程通信的一种特殊的进程间通信(IPC) ,也是网络应用程序与内核通信的最常用的接口。在Linux标准内核中&#xff0c;系统默认集成了很多netlink实例&#xff0c;比如日志上报、路由系统等&#xff0c;netlink消息是双向的&a…