5 Linux 网络编程基础 API

5 Linux 网络编程基础 API

主机字节序和网络字节序

  • 主机(小端)字节序:0x0201
  • 网络(大端)字节序:0x0102,利于人看
#include <netinet/in.h>
unsigned long int htonl(unsigned long int hostlong);
unsigned short int htonl(unsigned long int hostshort);
unsigned long int ntohl(unsigned long int hostlong);
unsigned short int ntohl(unsigned long int hostshort);

通用 socket 地址

#include <bits/socket.h>
// socket 地址结构体
struct sockaddr
{
    sa_family_t sa_family; // 地址族类型 ≈ 协议族类型
    char sa_data[14];
};

// 新的通用 socket 结构体
struct sockaddr_storage
{
    sa_family_t sa_family;
    unsigned long int __ss_align;
    char __ss_padding[128 - sizeof(__ss_align)];
};

专用 socket 地址

#include <bits/socket.h>
// UNIX 本地协议族
struct sockaddr_un
{
    sa_family_t sin_family; // AF_UNIX == PF_UNIX
    char sun_path[108];     // 文件路径名
};

// IPv4
struct sockaddr_in
{
    sa_family_t sin_family;  // AF_INET == PF_INET
    u_int16_t sin_port;      // 网络字节序
    struct in_addr sin_addr; // Ipv4 结构体地址
};
struct in_addr
{
    u_int32_t s_addr; // 网络字节序
};

IP 地址转换函数

// IPv4
#include <arpa/inet.h>
in_addr_t inet_addr(const char* strptr); // INADDR_NONE
int inet_aton(const char* cp, struct in_addr* inp);

// 函数内部有一个静态变量存储转化结果,返回值指向该静态内存
char* inet_ntoa(struct in_addr in);

创建 socket

#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
  • domain:底层协议族,PF_UNIX、PF_INET、PF_INET6
  • type:服务类型,
    • SOCK_STREAM ==> tcp
    • SOCK_UGRAM ==> UDP
    • SOCK_NONBLOCK 新创建的 socket 设为非阻塞的
    • SOCK_CLOEXEC 用 fork 调用创建子进程时在子进程中关闭该 socket
  • protocol:0
  • return:
    • 成功:socket 文件描述符
    • 失败:-1,errno

命名 socket

#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr* my_addr, socklen_t addrlen);
  • return:
    • 成功:0
    • 失败:-1,errno
      • EACCES:被绑定的地址是受保护的地址,仅超级用户能够访问,比如普通用户将 socket 绑定到知名端口
      • EADDRINUSE:被绑定的地址正在使用

监听 socket

#include <sys/socket.h>
int listen(int sockfd, int backlog);
  • backlog:提示内核监听队列的最大长度,完全处理连接状态的 socket 上线
    处于半连接状态的 socket 的上线由 /proc/sys/net/ipv4/tcp_max_syn_backlog 内核参数定义
  • return:
    • 成功:0
    • 失败:-1,errno

监听队列的长度如果超过 backlog,服务器将不受理新的客户端连接,客户端也将收到 ECONNEREFUSED 错误

接受连接

  • 监听 socket:执行过 listen 调用、处于 LISTEN 状态的 socket
  • 连接 socket:处于 ESTABLISHED 状态的 socket
#include <sys/types.h>
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen);
  • accept 只是从监听队列中取出连接,而不论连接处于何种状态,更不关心网络状况的变化
  • return:
    • 失败:-1,errno

发起连接

  • server 通过 listen 调用来被动接受连接
  • client 通过 connect 调用来主动与 server 建立连接
#include <sys/types.h>
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr* serv_addr, socklen_t addrlen);
  • return:
    • 失败:-1,errno
      • ECONNREUFUSED:目标端口不存在,拒绝被连接
      • ETIMEDOUT:连接超时

关闭连接

#include <unistd.h>
int close(int fd);
  • close 只有将引用计数减为 0 时,才真正关闭连接
#include <sys/socket.h>
int shutdown(int sockfd, int howto);
  • 可立即终止连接(无需计数变为 0
  • howto:
    • SHUT_RD:关闭读,丢弃接收缓冲区数据
    • SHUT_WR:关闭写,发送缓冲区的数据会在真正关闭写之前发送出去,半关闭状态
    • SHUT_RDWR:

TCP 数据读写

#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int sockfd, void* buf, size_t len, int flags);
  • return:
    • 0:通信对方关闭连接
    • -1:errno
ssize_t send(int sockfd, const void* buf, size_t len, int flags);
  • flags:通常 0,只对当前调用生效
flags含义sendrecv
MSG_CONFIRM指示数据链路层协议持续监听对方的回应,直到得到答复,只适用于 SOCK_DGRAM 和 SOCK_RAW 类型的 socketYN
MSG_DONTROUTE不查看路由表,直接将数据发送给本地局域网络内的主机,发送者知道目标主机就在本地网络上YN
MSG_DONTWAIT对 socket 的此次操作将是非阻塞的YY
MSG_MORE告诉内核应用程序还有更多数据要发送,内核将超时等待新数据写入 TCP 发送缓冲区后一并发送,可防止 TCP 发送过多小报文段,提高传输效率YN
MSG_WAITALL读操作仅在读取到指定数量的字节后才返回NY
MSG_PEEK窥探读缓存中的数据,此次读操作不会导致这些数据被清除NY
MSG_OOB发送或接受紧急数据YY
MSG_NOSIGNAL往读端关闭的管道或者 socket 连接中写数据时不引发 SIGPIPE 信号YN

只有最后一个字符被当成正真的带外数据接收,服务器对正常数据的接收将被带外数据截断

UDP 数据读写

#include <sys/types.h>
#include <sys/socket.h>
sszie_t recvfrom(int sockfd, void* buf, size_t len, int flags, struct sockaddr* src_addr, socklen_t* addrlen);
ssize_t sendto(int sockfd, const void* buf, size_t len, int flags, struct sockaddr* dest_addr, socklen_t addrlen);

这两个函数也可用于面向连接的 socket 的数据读写,只需要把最后两个参数设置为 NULL 以忽略发送端、接收端的 socket 地址,已经建立了连接,双方知道对方地址

通用数据读写函数

#include <sys/socket.h>
ssize_t recvmsg(int sockfd, struct msghdr* msg, int flags);
ssize_t sendmsg(int sockfd, struct msghdr* msg, int flags);

struct msghdr
{
    void* msg_name; // socket 地址
    socklen_t msg_namelen;
    struct iovec* msg_iov; // 分散的内存块
    int msg_iovlen; // 分散内存块数量
    void* msg_control; // 指向辅助数据的起始位置
    socklen_t msg_controllen;
    int msg_flags; // 赋值函数中的 flags 参数,并在调用过程中更新
};

struct iovec
{
    void* iov_base; // 内存起始地址
    size_t iov_len; // 这块内存长度 
};
  • msg_name:指定通信对方的 socket 地址,TCP 中为 NULL
  • 分散读:对于 recvmsg,数据将被读取并存放在 msg_iovlen 块分散的内存中,这些内存的位置和长度由 msg_iov 指向的数组决定
  • 集中写:对于 sendmsg,msg_iovlen 块分散内存中的数据将被一并发送
  • msg_flags:无需设定,会复制 recvmsg、sendmsg 的 flags 参数的内容以影响数据读写过程。recvmsg 还会在调用结束前,将某些更新后的标志设置到 msg_flags 中

带外标记
内核通知应用程序带外数据到达方式:

  • I/O 复用产生的异常事件
  • SIGURG 信号
#include <sys/socket.h>
int sockatmark(int sockfd);
  • 判断 sockfd 是否处于带外标记,即下一个被读取到的数据是否是带外数据

    • SO_LINGER:控制 close 系统调用关闭 TCP 连接时的行为
  • 建议 sock 在 listen 和 accept 之前设置选项信息

网络信息 API

#include <netdb.h>
// 获取主机的完整信息
/* 先在本地 /etc/hosts 配置文件中查找主机,再去 DNS 服务器 */
struct hostent* gethostbyname(const char* name);

/*
 * @param len 指定 addr 所指 IP 地址长度
 * @param type 指定 addr 所指 IP 地址类型
 */
struct hostent* gethostbyaddr(const void* addr, size_t len, int type);

struct hostent
{
    char* h_name; // 主机名
    char** h_aliases; // 主机别名
    int h_addrtype; // 地址类型
    int h_length; // 地址长度
    char** h_addr_list; // 网络字节序列出主机 IP 地址列表
};

// 获取服务的完整信息,通过读取 /etc/services 文件获取服务信息
/*
 * @param proto 服务类型
 *              tcp 获取流服务
 *              udp 获取数据报服务
 *              NULL 获取所有类型服务
 */
struct servent* getservbyname(const char* name, const char* proto);
struct servent* getservbyport(int port, const char* proto);

struct servent
{
    char* s_name; // 服务名称
    char** s_aliases; // 服务别名列表
    int s_port; // 端口号
    char* s_proto; // 服务类型 tcp or udp
};

/*
 * 根据主机名获得 IP 地址(`gethostbyname`)
 * 根据服务名获得 port(`getservbyname`)
 * 是否可冲入取决于内部调用的方法
 * 
 */
int getaddrinfo(const char* hostname, const char* service, const struct addrinfo* hints, struct addrinfo** result);

struct addrinfo
{
    int ai_flags;
    int ai_family;
    int ai_socktype;
    int ai_protocol;
    socklen_t ai_addrlen;
    char* ai_canonname;
    struct sockaddr* ai_addr;
    struct addrinfo* ai_next;
};

void freeaddrinfo(struct addrinfo* res);

int getnameinfo(const struct sockaddr* sockaddr, socklen_t addrlen, char* host, socklen_t hostlen, char* serv, socklen_t servlen, int flags);

/* 将 getaddrinfo 和 getnameinfo 返回的错误码转换为字符串形式 */
const char* gai_strerror(int error);

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux-Ubuntu之I2C通信

Linux-Ubuntu之I2C通信 一&#xff0c;I2C通信原理1.写时序2.读时序 二&#xff0c;代码实现三&#xff0c;显示 一&#xff0c;I2C通信原理 使用I2C接口驱动AP3216C传感器&#xff0c;该传感器能实现两个效果&#xff0c;一个是感应光强&#xff0c;另一个是探测物体与传感器…

音视频入门基础:MPEG2-PS专题(4)——FFmpeg源码中,判断某文件是否为PS文件的实现

一、引言 通过FFmpeg命令&#xff1a; ./ffmpeg -i XXX.ps 可以判断出某个文件是否为PS文件&#xff1a; 所以FFmpeg是怎样判断出某个文件是否为PS文件呢&#xff1f;它内部其实是通过mpegps_probe函数来判断的。从《FFmpeg源码&#xff1a;av_probe_input_format3函数和AVI…

框架模块说明 #09 日志模块_01

背景 日志模块是系统的重要组成部分&#xff0c;主要负责记录系统运行状态和定位错误问题的功能。通常&#xff0c;日志分为系统日志、操作日志和安全日志三类。虽然分布式数据平台是当前微服务架构中的重要部分&#xff0c;但本文的重点并不在此&#xff0c;而是聚焦于自定义…

【数据仓库】hadoop3.3.6 安装配置

文章目录 概述下载解压安装伪分布式模式配置hdfs配置hadoop-env.shssh免密登录模式设置初始化HDFS启动hdfs配置yarn启动yarn 概述 该文档是基于hadoop3.2.2版本升级到hadoop3.3.6版本&#xff0c;所以有些配置&#xff0c;是可以不用做的&#xff0c;下面仅记录新增操作&#…

算法题(25):只出现一次的数字(三)

审题&#xff1a; 该题中有两个元素只出现一次并且其他元素都出现两次&#xff0c;需要返回这两个只出现一次的数&#xff0c;并且不要求返回顺序 思路: 由于对空间复杂度有要求&#xff0c;我们这里不考虑哈希表。我们采用位运算的方法解题 方法&#xff1a;位运算 首先&#…

将机器学习预测模型融入AI agent的尝试(一)

将机器学习临床预测模型融入AI agent的尝试&#xff08;一&#xff09; 我主要是使用机器学习制作临床预测模型和相关的应用&#xff0c;最近考虑的事情是自己之前的的工作能不能和AI agent进行融合&#xff0c;将AI 对自然语言理解能力和预测模型的预测能力结合在一起&#x…

51单片机——按键实验

由于机械点的弹性作用&#xff0c;按键开关在闭合时不会马上稳定的接通&#xff0c;在断开时也不会一下子断开&#xff0c;因而在闭合和断开的瞬间均伴随着一连串的抖动。抖动时间的长短由按键的机械特性决定的&#xff0c;一般为 5ms 到 10ms&#xff0c;为了确保 CPU 对按键的…

电子邮件对网络安全的需求

&#xff08; 1&#xff09;机密性&#xff1a;传输过程中不被第三方阅读到邮件内容&#xff0c;只有真正的接收方才可以阅读邮件。&#xff08; 1.5 分&#xff09; &#xff08; 2&#xff09;完整性&#xff1a;支持在邮件传输过程中不被篡改&#xff0c;若发生篡改&#…

vue路由模式面试题

vue路由模式 1.路由的模式有哪些?有什么区别? history和hash模式 区别: 1.表现的形态不同: 在地址栏url中:hash模式中带有**#**号,history没有 2.请求错误时表现不同: 在hash模式中,对于404地址请求时,不会进行请求 但是在history模式中,对于404请求时,仍然会进行请求…

电子应用设计方案86:智能 AI背景墙系统设计

智能 AI 背景墙系统设计 一、引言 智能 AI 背景墙系统旨在为用户创造一个动态、个性化且具有交互性的空间装饰体验&#xff0c;通过融合先进的技术和创意设计&#xff0c;提升室内环境的美观度和功能性。 二、系统概述 1. 系统目标 - 提供多种主题和风格的背景墙显示效果&…

Python爬虫 - 豆瓣图书数据爬取、处理与存储

文章目录 前言一、使用版本二、需求分析1. 分析要爬取的内容1.1 分析要爬取的单个图书信息1.2 爬取步骤1.2.1 爬取豆瓣图书标签分类页面1.2.2 爬取分类页面1.2.3 爬取单个图书页面 1.3 内容所在的标签定位 2. 数据用途2.1 基础分析2.2 高级分析 3. 应对反爬机制的策略3.1 使用 …

西安电子科技大学初/复试笔试、面试、机试成绩占比

西安电子科技大学初/复试笔试、面试、机试成绩占比 01通信工程学院 02电子工程学院 03计算机科学与技术学院 04机电工程学院 06经济与管理学院 07数学与统计学院 08人文学院 09外国语学院 12生命科学与技术学院 13空间科学与技术学院 14先进材料与纳米科技学院 15网络与信息安…

多模态论文笔记——CogVLM和CogVLM2(副)

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍多模态模型的LoRA版本——CogVLM和CogVLM2。在SD 3中使用其作为captioner基准模型的原因和优势。 文章目录 CogVLM论文背景VLMs 的任务与挑战现有方法及…

智慧工地信息管理与智能预警平台

建设背景与政策导向 智慧工地信息管理与智能预警平台的出现&#xff0c;源于工地管理面临的诸多挑战&#xff0c;如施工地点分散、危险区域多、监控手段落后等。随着政府对建筑产业现代化的积极推动&#xff0c;各地纷纷出台政策支持智慧工地的发展&#xff0c;旨在通过信息技…

【从零开始入门unity游戏开发之——C#篇42】C#补充知识——随机数(Random)、多种方法实现string字符串拼接、语句的简写

文章目录 一、随机数1、Random.Next()生成随机整数示例&#xff1a;生成一个随机整数生成指定范围内的随机整数 2、Random.NextSingle生成随机浮点数示例&#xff1a;生成随机浮点数 3、 生成随机字母或字符示例&#xff1a;生成随机字母示例&#xff1a;生成随机小写字母 二、…

「Mac畅玩鸿蒙与硬件54」UI互动应用篇31 - 滑动解锁屏幕功能

本篇教程将实现滑动解锁屏幕功能&#xff0c;通过 Slider 组件实现滑动操作&#xff0c;学习事件监听、状态更新和交互逻辑的实现方法。 关键词 滑动解锁UI交互状态管理动态更新事件监听 一、功能说明 滑动解锁屏幕功能包含以下功能&#xff1a; 滑动解锁区域&#xff1a;用…

VScode SSH 错误:Got bad result from install script 解決

之前vscode好好的&#xff0c;某天突然连接报错如下 尝试1. 服务器没有断开,ssh可以正常连接 2. 用管理员权限运行vscode&#xff0c;无效 3. 删除服务器上的~/.vscode-server 文件夹&#xff0c;无效 试过很多后&#xff0c;原来很可能是前一天anaconda卸载导致注册表项 步…

[论文笔记]Representation Learning with Contrastive Predictive Coding

引言 今天带来论文 Representation Learning with Contrastive Predictive Coding的笔记。 提出了一种通用的无监督学习方法从高维数据中提取有用表示&#xff0c;称为对比预测编码(Contrastive Predictive Coding,CPC)。使用了一种概率对比损失&#xff0c; 通过使用负采样使…

【C#深度学习之路】如何使用C#实现Yolo5/8/11全尺寸模型的训练和推理

【C#深度学习之路】如何使用C#实现Yolo5/8/11全尺寸模型的训练和推理 项目背景项目实现调用方法项目展望写在最后项目下载链接 本文为原创文章&#xff0c;若需要转载&#xff0c;请注明出处。 原文地址&#xff1a;https://blog.csdn.net/qq_30270773/article/details/1449186…

如何很快将文件转换成另外一种编码格式?编码?按指定编码格式编译?如何检测文件编码格式?Java .class文件编码和JVM运行期内存编码?

如何很快将文件转换成另外一种编码格式? 利用VS Code右下角的"选择编码"功能&#xff0c;选择"通过编码保存"可以很方便将文件转换成另外一种编码格式。尤其&#xff0c;在测试w/ BOM或w/o BOM, 或者ANSI编码和UTF编码转换&#xff0c;特别方便。VS文件另…