`

字节转换和填充函数

阅读更多
    网络编程中,为保证发送协议栈和接收协议栈就如 32 位 IPv4 地址等多字节字段各个分节的传送顺序一致,经常需要在主机字节序和网络字节序之间进行转换。这种转换就是利用以下 4 个函数来实现的。
#include <netinet/in.h>
uint16_t htons(uint16_t host16bitvalue);
uint32_t htonl(uint32_t host32bitvalue);
                           /* 返回值:均为网络字节序的值 */
uint16_t ntohs(uint16_t net16bitvalue);
uint32_t ntohl(uint32_t net32bitvalue);
                           /* 返回值:均为主机字节序的值 */

    在这些函数的名字中,h 代表 host,n 代表 network,s 代表 short,l 代表 long。当使用这些函数时,我们并不关心主机字节序和网络字节序的真实值(大端还是小端),只是调用适当的函数在主机和网络字节序之间转换某个给定值。在那些与网际协议所用字节序(大端)相同的系统中,这四个函数通常被定义为空宏。
   
    操作多字节字段的函数有两组,它们既不对数据作解释,也不假设数据是以空字符结束的 C 字符串。在处理套接字地址结构时就经常需要这些类型的函数,因为诸如 IP 地址这样的字段中可能包含有值为 0 的字节,但却不是 C 字符串。
    名字以 b(表示字节)开头的第一组函数起源于 4.2 BSD。名字以 mem(表示内存)开头的第二组函数起源于 ANSI C 标准。
#include <strings.h>
void bzero(void *dest, size_t nbytes);
void bcopy(const void *src, void *dest, size_t nbytes);
int bcmp(const void *ptr1, const void *ptr2, size_t nbytes);
                                   /* 返回值:相等则为 0,否则为非 0 */

#include <string.h>
void *memset(void *dest, int c, size_t len);
void *memcpy(void *dest, const void *src, size_t nbytes);
int memcmp(const void *ptr1, const void *ptr2, size_t nbytes);
             /* 返回值:ptr1==ptr2,返回 0;ptr1<ptr2,返回负数;否则返回正数 */

    bzero 把目标字节串中指定数目的字节置为 0。经常使用该函数来把一个套接字地址结构初始化为 0。bcopy 将指定数目的字节从源字节串移到目标字节串。bcmp 比较两个任意的字节串。
    memset 把目标字节串指定数目的字节置为 c。memcpy 类似 bcopy,不过两个指针参数的顺序是相反的,而且当源字节串与目标字节串重叠时,bcopy 能够正确处理,但 memcpy 的操作结果却不可知(这种情形下必须改用 ANSI C 的 memmove 函数)。memcmp 比较两个任意的字节串。

    下面介绍两组在 ASCII 字符串和网络字节序的二进制值之间转换网际地址的地址转换函数。
    1、inet_aton、inet_addr(目前已废弃)和 inet_ntoa 在点分十进制和网络字节序间转换 IPv4 地址。
    2、inet_pton 和 inet_ntop 对于 IPv4 和 IPv6 地址都适用。函数名中的 p 和 n 分别代表表达(presentation)和数值(numeric)。地址的表达格式通常是 ASCII 字符串,数值格式则是存放到套接字地址机构中的二进制值。
#include <arpa/inet.h>

int inet_aton(const char *strptr, struct in_addr *addrptr);
                                   /* 返回:若字符串有效则为 1,否则为 0 */
in_addr_t inet_addr(const char *strptr);
           /* 返回:若字符串有效则为网络字节序的 IPv4 地址,否则为 INADDR_NONE */
char *inet_ntoa(struct in_addr inaddr);
                                   /* 返回:指向一个点分十进制数串的指针 */

int inet_pton(int family, const char *strptr, void *addrptr);
        /* 返回:若成功,则为 1;若输入不是有效的表达格式则为 0;若出错则为 -1 */
const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len);
                            /* 返回:若成功则为指向结果的指针,否则为 NULL */

    inet_aton 将 strptr 所指的 C 字符串转换成 32 位的网络字节序二进制值,并通过 addrptr 指针来存储。该函数有一个没写入正式文档中的特征:若 addrptr 指针为空,则函数仍然对输入的字符串执行有效性检查,但是不存储任何结果。
    inet_ntoa 将一个 32 位的网络字节序二进制 IPv4 地址转换成相应的点分十进制。由该函数的返回值所指向的字符串驻留在静态内存中。这意味着该函数是不可重入的。
    inte_pton 和 inet_ntop 的 family 参数既可以为 AF_INET,也可以为 AF_INET6,其它不被支持的值都将使这两个函数返回一个错误,并将 errno 置为 EAFNOSUPPORT。inet_pton 将 strptr 指针所指的字符串转换成二进制值,并通过 addrptr 指针存放。inet_ntop 进行相反的转换,从数值格式转换到表达格式。len 参数是目标存储单元的大小,以免该函数溢出其调用者的缓冲区。为有助于指定这个大小,在 <netinet/in.h> 中有如下定义:
        #define INET_ADDRSTRLEN    16      // for IPv4 dotted-decimal
        #define INET6_ADDRSTRLEN   46      // for IPv6 hex string
    若 len 太小,不足以容纳表达格式结果(包括结尾的空字符),那么返回一个空指针,并将 errno 置为 ENOSPC。
    inet_ntop 中的 strptr 参数不可以是一个空指针。调用者必须为目标存储单元分配内存并指定其大小。调用成功时,该指针就是该函数的返回值。
    下面给出了只支持 IPv4 的 inet_pton 和 inet_ntop 函数的简单定义。
int inet_pton(int family, const char *strptr, void *addrptr){
    if(family == AF_INET){
        struct in_addr in_val;
        if(inet_aton(strptr, &in_val)){
            memcpy(addrptr, &in_val, sizeof(struct in_addr));
            return 1;
        }
        return 0;
    }
    errno = EAFNOSUPPORT;
    return -1;
}

const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len){
    const u_char *p = (const u_char *)addrptr;
    if(family == AF_INET){
        char temp[INET_ADDRSTRLEN];
        snprintf(temp, sizeof(temp), "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
        if(strlen(temp) >= len){
            errno = ENOSPC;
            return NULL;
        }
        strcpy(strptr, temp);
        return strptr;
    }
    errno = EAFNOSUPPORT;
    return NULL;
}
分享到:
评论

相关推荐

    高低字节转换工具VB

    高低字节转换工具主要功能是在发送数据时将整数值按照特定规则转换为高位字节和低位字节,以便于通过串行通信等接口传输。这个过程通常涉及到将整数转换为二进制表示,然后进一步分割为高位和低位两个部分。 #### ...

    vb6.0 字节数组和字符串的相互转换.rar

    总结:在VB6.0中,字节数组和字符串的相互转换主要依赖于`StrConv`函数,以及辅助的`MidB`和`LenB`函数。了解这些基本操作对于处理二进制数据和文本数据至关重要。在实际项目中,这些功能广泛应用于文件读写、网络...

    字节转换

    内存对齐和字节填充有时会影响字节转换的过程,尤其是在优化性能或跨平台兼容性时。 8. **加密解密**:在加密算法中,字节转换是必不可少的步骤。比如AES加密算法,输入的数据和密钥都需要转换成字节数组才能进行...

    易语言图片句柄取图片字节集

    3. 转换为字节集:将获取到的图片二进制数据转换成字节集,易语言提供了`创建字节集`或`复制字节集`函数,将图片数据填充到字节集中。 4. 使用或存储字节集:转换后的字节集可以保存到文件,也可以在网络上传输,...

    数据库函数数据库函数.doc

    本文将对常用的数据库函数进行详细的介绍,包括字符函数、字符串替代函数、字符级替代函数、大小写转换函数、连接函数、搜索函数、填充函数等。 字符函数 字符函数是数据库函数中的一种,用于处理字符串类型的数据...

    基64字节数组转基64字符串

    函数通过一个`switch`语句处理这种情况,根据剩余字节数的多少进行适当的位操作和填充,以确保生成的Base64字符串是完整的。 5. 最后,函数返回生成的Base64字符串,这个字符串可以直接插入到HTML的`&lt;img&gt;`标签的`...

    Delphi版的Base64互相转换函数

    在Delphi编程环境中,处理Base64编码和解码是常见的需求,这涉及到字符串与二进制数据之间的转换。 本主题聚焦于在Delphi中实现Base64的编码和解码功能。首先,我们需要理解Base64的基本原理。Base64使用64个字符...

    易语言经典教程_字节集

    本文将详细介绍字节集的概念、特点以及易语言中提供的各种字节集操作函数,帮助读者更好地理解和应用这一功能。 #### 二、字节集的基本概念 字节集本质上是一种由多个字节组成的数组,每个字节代表8位二进制信息。...

    DLL参数传递字节集.rar

    在Windows操作系统中,动态链接库(DLL)是一种可重用代码的模块,它包含可由多个执行程序同时使用的函数和资源。DLL参数传递字节集是DLL编程中的一个重要概念,涉及如何有效地在调用者(应用程序)和被调用者(DLL...

    oracle系统内置函数大全

    Oracle数据库系统内置了大量函数,这些函数可以分为多个类别,例如字符函数、数字函数、日期函数、转换函数、分组函数以及其他辅助函数等。以下是对每个类别中一些常用函数的详细介绍: 字符函数 1. ASCII函数:...

    易语言字节集转位图功能源码

    在IT行业中,字节集(Byte Array)是一种常见的数据结构,用于...通过理解和应用以上步骤及函数,开发者可以实现易语言中字节集与位图之间的相互转换,这在处理图像数据、网络传输或者文件存储等场景下具有广泛的应用。

    Excel2019函数列表 (按字母)

    例如,ASC函数将字符串中的全角(双字节)英文字母或片假名字符更改为半角(单字节)字符。这一功能对于那些需要将数据从一种语言环境转换到另一种语言环境的用户来说非常便利。 统计函数在数据分析中占据重要地位...

    易语言字节集补位前移后移

    易语言提供了多种操作字节集的内置函数和命令。 2. **补位算法**:学习如何根据特定规则(如字节对齐、填充特定值等)进行补位操作,确保数据满足特定条件。 3. **数据移动**:掌握如何前移或后移字节集中的数据,...

    易语言字节集到易格式文本对比

    通过学习和理解这些源码,开发者可以了解到如何在易语言中进行字节集和易格式文本之间的转换,并进行有效的比较,这对于编写涉及数据校验、文件解析等场景的程序非常有用。 此外,"字节集到易格式文本_内存"、"字节...

    易语言显示字节集源码.rar

    在易语言中,这通常需要使用到一系列的内建命令,如“字节集到字符串”(将字节集转换为字符串)和“取字节集长度”(获取字节集的大小)等。 源码中可能涵盖了以下知识点: 1. **字节集创建与初始化**:如何创建...

    mysql函数大全.pdf

    10. CHAR_LENGTH函数和CHARACTER_LENGTH函数 CHAR_LENGTH函数返回字符串的字符数,而CHARACTER_LENGTH函数是它的同义词。 ```sql SELECT CHAR_LENGTH('text'); -- 返回字符串 'text' 的字符数 ``` 11. LOCATE函数和...

    c语言的base64编解码函数

    它将任意的二进制数据转换为可打印的ASCII字符序列,以7位ASCII字符进行编码,每3个字节转换为4个6位的字符,最后用'='字符对不足4组的数据进行填充。C语言中的Base64编解码函数可以帮助开发者在程序中实现这种转换...

    实现字节数组同c中的字符数组一样好用(6KB)...

    在`string.bas`和`string.frm`这两个源代码文件中,开发者可能已经实现了一些函数和过程,用于字节数组的操作,如初始化、复制、拼接和查找。这些功能的实现可能包括对每个字节进行遍历,以及使用VB的内建函数,如`...

    易语言DLL参数传递字节集

    这个函数可以方便地将各种类型的数据转换为字节集形式,以便于传递给DLL。 2. **RtlMoveMemory函数**:这是一个Windows API中的内存拷贝函数,它在易语言中通常通过`_d`后缀来调用,表示动态链接。`RtlMoveMemory_d...

    易语言源码字节集替换.rar

    易语言提供了丰富的字节集处理函数,如“字节集到整数”、“整数到字节集”、“字节集到字符串”等,可以方便地在字节集与其他数据类型之间转换。同时,还可以使用“字节集长度”获取字节集的大小,以及“字节集复制...

Global site tag (gtag.js) - Google Analytics