第五章 Linux网络编程基础API

embedded/2025/2/5 17:56:08/

在网络编程中,“网络字节序”(Network Byte Order)指的是一种统一的字节排列方式,即大端字节序(Big-Endian),用于在网络上传输数据。这样做的目的是确保不同主机之间(可能采用不同的字节序)能够正确地解析数据。

#include <stdio.h>

void byteorder()

{

 union{

        short value;

        char union_bytes[sizeof(short)];

}test;

test.value = 0x0102;

if( ( test.union_bytes[0] == 1 && test.union_bytes[1] == 2)

{

        printf("big endian\n");
}else if( test.union_bytes[0] == 2 && test.union_bytes[1] == 1){
printf("little endian\n");
}else{

printf("unknown...\n");
}

IP地址转换函数

struct in_addr

{

        u_int32_t s_addr;
}

#include <arpa/inet.h>

int_addr_t inet_addr(const char* strptr);

int inet_aton(const char* cp,struct in_addr* inp);

char* inet_ntoa(struct in_addr in); // 不可重入

int inet_pton(int af, const char* src, void * dst);

const char* inet_ntop(int af, const void* src,char *dst,socklen_t cnt);

// 以上涉及的ip 地址的数字表示都是网络字节序

struct in_addr addr;

addr.s_addr = inet_addr("192.168.1.1");

char ip_str[INET_ADDRSTRLEN]; // 通常为 16 字节

if (inet_ntop(AF_INET, &addr, ip_str, INET_ADDRSTRLEN) != NULL)

{ printf("IP地址为: %s\n", ip_str); } else { perror("inet_ntop"); }

#include <stdio.h>
#include <arpa/inet.h>

int main() {
    const char *ip_str = "192.168.1.1";  // 待转换的 IPv4 地址字符串
    struct in_addr addr;

    // 使用 inet_pton 进行转换
    // AF_INET 表示 IPv4,&addr 是存放转换结果的地址
    int result = inet_pton(AF_INET, ip_str, &addr);
    if (result == 1) {
        // 转换成功,addr.s_addr 存放的是网络字节序的地址
        printf("IPv4地址转换成功!\n");
        printf("网络字节序的地址值:0x%x\n", addr.s_addr);
    } else if (result == 0) {
        // 输入的地址字符串格式不正确
        fprintf(stderr, "无效的IPv4地址格式: %s\n", ip_str);
        return 1;
    } else {
        // 转换过程中出现错误
        perror("inet_pton");
        return 1;
    }

    return 0;
}
 

1.创建socket

#include <sys/types.h>

#include <sys/socket.h>

int socket(int domain, int type, int protocol);// 失败返回-1 并设置errno

domain: PF_INET (IPV4) 或者 PF_INET6(IPV6)对于unix 本地域协议族为PF_UNIX

type 指定服务类型      SOCK_STREAM(流服务)表示传输层使用TCP协议

SOCK_DGRAM (数据报服务)表示传输层使用udp协议

protocol 通常为0

2.命名socket

#include <sys/types.h>

#inclulde <sys/socket.h>

int bind(int sockfd,const struct sockaddr* my_addr,socklen_t addrlen);

bind 将my_addr所指的socket 地址分配给未命名的sockfd文件描述符,addrlen参数指出该sockaddr的长度

3.监听socket

#include <sys/socket.h>

int listen(int sockfd, int backlog);

sockfd 参数指定被监听的socket, backlog 参数提示内核监听队列的最大长度。

4.接受连接

#include <sys/types.h>

#include <sys/socket.h>

int accept(int sockfd, struct sockaddr* addr, socklen_t * addrlen);

sockfd 参数是执行过listen 系统调用的监听socket。addr 参数用来获取被接受连接的远端socket地址,该sockaddr 参数的长度由addrlen 参数指出

accetp 失败返回-1  并设置errno

5.发起连接

#include <sys/types.h>

#include <sys/socket.h>

int connect( int sockfd, const struct sockaddr* serv_addr, socklen_t addrlen);

sockfd 参数由socket系统调用返回一个socket,serv_addr 参数是服务器监听的socket地址,addrlen参数指定sockaddr 的长度。

connect 成功返回0,一旦成功建立连接,sockfd 就唯一标识了这个连接,客户端可以通过读写sockfd来与服务器通信。connect失败返回-1并设置errno 

6.关闭连接

#include <unistd.h>

int close(int fd);

close 并不是直接关闭对应的fd 连接,而是将fd的引用计数减1.只有当fd的引用计数为0时,才可以真正关闭socket。一次fork系统调用默认将使父进程中打开的socket的引用加1,必须在子进程和父进程中都对socket执行close调用才能将连接关闭。

如果要立即关闭可以使用shutdown

#include <sys/socket.h>

int shutdown(int sockfd, int howto);

sockfd 是待关闭的socket  howto 决定了shutdown的行为

SHUT_RD   应用程序不可以再对sockfd进行读操作

SHUT_WR  不可以写操作

SHUT_RDWR 同事关闭读写

成功返回0失败返回-1并设置errno


http://www.ppmy.cn/embedded/159809.html

相关文章

MR-GDINO: Efficient Open-World Continual Object Detection—— 高效开放世界持续目标检测

这篇文章提出了一种名为MR-GDINO的开放世界持续目标检测方法&#xff0c;旨在解决开放世界检测器在持续学习过程中对已见类别和未见类别的灾难性遗忘问题。文章的主要内容和贡献如下&#xff1a; 问题定义&#xff1a;提出了开放世界持续目标检测任务&#xff0c;要求检测器在持…

自定义数据集 使用pytorch框架实现逻辑回归并保存模型,然后保存模型后再加载模型进行预测,对预测结果计算精确度和召回率及F1分数

代码&#xff1a; import torch import numpy as np import torch.nn as nn from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score# 定义数据&#xff1a;x_data 是特征&#xff0c;y_data 是标签&#xff08;目标值&#xff09; data [[-0…

二、CSS笔记

(一)css概述 1、定义 CSS是Cascading Style Sheets的简称,中文称为层叠样式表,用来控制网页数据的表现,可以使网页的表现与数据内容分离。 2、要点 怎么找到标签怎么操作标签对象(element) 3、css的四种引入方式 3.1 行内式 在标签的style属性中设定CSS样式。这种方…

小程序设计和开发:要如何明确目标和探索用户需求?

一、明确小程序的目标 确定业务目标 首先&#xff0c;需要明确小程序所服务的业务领域和目标。例如&#xff0c;是一个电商小程序&#xff0c;旨在促进商品销售&#xff1b;还是一个服务预约小程序&#xff0c;方便用户预订各类服务。明确业务目标有助于确定小程序的核心功能和…

(10) 如何获取 linux 系统上的 TCP 、 UDP 套接字的收发缓存的默认大小,以及代码范例

&#xff08;1&#xff09; 先介绍下后面的代码里要用到的基础函数&#xff1a; 以及&#xff1a; &#xff08;2&#xff09; 接着给出现代版的 读写 socket 参数的系统函数 &#xff1a; 以及&#xff1a; &#xff08;3&#xff09; 给出 一言的 范例代码&#xff0c;获取…

HarmonyOS NEXT:保存应用数据

用户首选项使用 用户首选项的特点 数据体积小、访问频率高、有加载速度要求的数据如用户偏好设置、用户字体大小、应用的配置参数。 用户搜选项&#xff08;Preferences&#xff09;提供了轻量级配置数据的持久化能力&#xff0c;支持订阅数据变化的通知能力。不支持分布式同…

全面掌握市场信息:xtquant库在证券品种数据获取中的应用

全面掌握市场信息&#xff1a;xtquant库在证券品种数据获取中的应用 开篇点题&#xff1a;技术背景和应用场景 在量化交易领域&#xff0c;快速准确地获取市场基础信息是至关重要的。xtquant库提供了一种便捷的途径来获取各类证券品种的数据&#xff0c;包括股票、指数、基金等…

【LeetCode 刷题】贪心算法(1)-基础

此博客为《代码随想录》二叉树章节的学习笔记&#xff0c;主要内容为贪心算法基础的相关题目解析。 文章目录 455.分发饼干1005.K次取反后最大化的数组和860.柠檬水找零 455.分发饼干 题目链接 class Solution:def findContentChildren(self, g: List[int], s: List[int]) -…