UNIX网络编程学习笔记2 需要用到的一些字节操纵和格式转换函数

当然这些东西是炒鸡无聊的,但是真当自己开始撸代码时才发现熟悉这些枯燥的函数能够节约大量的时间。于是总结一下:

字节序:低序字节存储在起始地址,这称为小端(little-endian),高序字节存储在起始地址,这称为大端(big-endian)

例:存放0x0A0B0C0D

LE: 0D 0C 0B 0A

BE: 0A 0B 0C 0D

小端的存放方式更加接近于人类思维

网际协议使用大端字节序来传送多字节整数(为何要规定一个字节序来传输ip和port? 呸 这样子协议才能正确“看懂”(解释)这些地址  你自己的数据当然可以不转 不过客户端和服务端解释数据的方式(字节序)要统一  自己的数据并不是协议的内容  所以不必用协议的规范来约束自己的数据  不过当然转了更好 谁叫大家都这样做0.0)

下面是字节排序函数:

1 #include<netinet /in.h>
2 unit16_t htons(uint16_t host16bitvalue);
3 unit32_t htonl(uint32_t host32bitvalue);//上面两个返回网络字节序(BE)的值,下面两个返回主机字节序(由实现定义)的值
4 uint16_t ntohs(uint16_t net16bitvalue);
5 unit32_t nothl(unit32_t net32bitvalue);

这些函数的名字中,h代表host,n代表network,s代表short,l代表long。

由于这些东西都是老古董,所以此处的s和l分别应该视为一个16位的值和一个32位的值。

两个使用排序函数的例子:设置ipv4套接字地址时 -> servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

            绑定端口时 -> servaddr.sin_port = htons(13);

接下来要说明的是一些字节操纵函数:

1 #include<strings.h>
2 void bzero(void *dest, size_t nbytes);
3 void bcopy(const void *src, void *dest, size_t nbytes);
4 int bcmp(const void *ptr1, const void *ptr2, size_t nbytes);//相等返回0,不相等返回非0.与memcmp不同。

没什么好说的,这些东西和mem*这类函数差不多(允许我这个正则渣渣用一个逗比的通配符23333)只不过更方便了,一个技巧识别这些函数和mem*函数的区别就是看const限定符,反正函数是从有这个限定符的参数中取值的。

地址转换函数:

ipv4:

1 #include<arpa/inet.h>
2 int inet_aton(const char *strptr, struct in_addr *addrptr);//若字符串有效返回1, 否则返回0。
3 in_addr_t inet_addr(const char *strptr);//这个函数已经被废弃
4 char *inet_ntoa(struct in_addr inaddr);//返回一个指向点分十进制数串的指针。

这里的三个函数暂时没啥好讨论的  我们来看一下下面两个新函数:

两个新函数:

#include<arpa/inet.h>
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。

这两个函数是对ipv4和ipv6都适用的,family参数可以是两个(AF_INET, AF_INET6)如果以不被支持的地址族作为参数,则这两个函数都会返回一个错误,并将errno置为EAFNOSUPPORT(Address family not supported by protocol)。

函数名中的p代表“表达”(presentation) n代表“数值”(numeric)

说啥都不如一个例子来得快23333(其实是懒,就问你们桌面6不6)

(上面这个程序如果不声明套接字地址结构的话就会报段错误,然而我自己并未用到那个结构,估计和函数实现有关,留待日后解决)

关于len参数:len参数是目标存储单元的大小,以免该函数溢出其调用者的缓冲区。为有助于指定这个大小,定义了如下常数:

1 #include<netinet/in.h> 2 #define INET_ADDRSTRLEN 16 3 #define INET6_ADDRSTRLEN 46

如len过小不足以容纳表达式结果,那么返回一个NULL,并置errno为ENOSPC(No space left on device).

来张图总结一下五个函数(书上图):

好了 这次写到这暂时歇歇 其实本来要把书上给的非标准函数和这章的I\O也总结一下

可是突然不想写了 任性 23333

给自己的理由是有关于这篇文章的名字所包含的内容

已经总结完成  <---套路O(∩_∩)O蛤蛤蛤

以后还会继续努力的  嗯 就酱。

时间: 2024-12-22 10:49:00

UNIX网络编程学习笔记2 需要用到的一些字节操纵和格式转换函数的相关文章

Unix网络编程学习笔记之第6章 I/O复用:select和poll函数

一.I/O复用应用场合 1. 当客户处理多个描述符(既有标准输入,又有网络套接字)时,必须使用IO复用. 2. 一个客户同时处理多个套接字是可能的. 3. 如果一个服务器既要处理监听套接字,又要处理已连接套接字,一般就要使用I/O复用. 4. 如果一个服务器既要处理TCP,又要处理UDP,一般就要I/O复用. 5. 如果一个服务器要处理多个服务或协议,就要用到I/O复用. 其实IO复用就是一个进程/线程处理多个套接字描述符. 二. I/O模型 Unix提供了5种I/O模型: 1. 阻塞式I/O模

Unix网络编程学习笔记之第11章 名字与地址转换

一. 域名系统(DNS) 1. 简介 DNS主要用于主机名和IP地址之间的映射. 主机名可以是简单的名字ljm,也可以是全限定域名ljm.localdomainbaidu.com等. 2.资源记录 DNS中的条目称为资源记录(RR).我们感兴趣的RR类型只有几个: A             A记录把一个主机名映射为一个32位的IPv4地址. AAAA    4A记录把一个主机名映射为一个128位的IPv6地址. 例如: ljm               IN      A    127.0.

Unix网络编程学习笔记之第2章 TCP和UDP

TCP 1. TCP面向连接的协议,是一个字节流协议,没有任何记录边界.发送的是数据分组. 2. TCP提供了可靠性:确认重传和重组 (1) TCP每发送一份数据都会要求对端进行确认.如果超时,就会重传.TCP会估计往返时间RTT,以确定等待多长时间重传. (2) 如果多次发送数据分组,TCP可以保证分组的按序达到.即会根据序列号进行重组. 3. TCP提供流量控制 TCP在任何时刻通知对端,它此时一次能够接受多少字节的数据,即通告窗口.该窗口指出接受缓冲区当前可用的空间. 4. 为何说TCP是

Unix网络编程学习笔记之第7章 套接字选项

一.获取/设置套接字选项的方法 一个套接字描述符相关联的套接字选项很多.获取/设置套接字选项的方法: 1.  getsockopt和setsockopt函数 2. fcntl函数 3. ioctl函数 二. getsockopt和setsockopt函数 int getsockopt(int sockfd, int level, int optname, void* optval, socklen_t* optlen); int setsockopt(int sockfd, int level,

Unix网络编程学习笔记之第8章 基于UDP套接字编程

一. UDP C/S的典型函数调用 UDP没有像TCP那样的连接,客户端直接sendto向某服务器发送数据,服务器端一直recvfrom阻塞,以接收任何客户端发送的数据. 二. sendto和recvfrom函数 int sendto(int sockfd, const void* buff, size_t nbytes, int flag, const struct sockaddr* to, socklen_taddrlen); int recvfrom(int sockfd, void*

Unix网络编程学习笔记之第1章 简介

一.一个简单的时间获取客户端 #include <sys/socket.h> #define MAXCON 50 #define MAXLINE 1024 #define PORT 13 void err_sys(const char* s) { fprintf(stderr, "%s\n",s); exit(1); } int main(int argc, char** argv) { int sockfd; structsockaddr_in servaddr; cha

Unix网络编程学习笔记之第5章 TCP客户端/服务器程序示例

一. 一个简单TCP回射服务端程序 #include "unp.h" #define MAXLINE 1024 #define PORT 13 #define CONMAX 5 void err_sys(const char* s) { fprintf(stderr, "%s\n",s); exit(1); } void str_echo(int connfd) { int nbyte; char buff[MAXLINE+1]; again: while(nbyt

Unix网络编程学习笔记之第12章 IPv4与IPv6的互操作性

一. 简介 假设我们本章讨论的主机都是支持双栈的,即支持IPv4地址,也支持Ipv6地址. 我们本次讨论的点:客户端与服务器端使用的是不同类型的地址.因为相同类型的地址没什么可讲的. 二. IPv4客户端与IPv6服务器 即,客户端使用IPv4地址套接字来通信,服务器端使用IPv6地址套接字通信. 原理: 0. 首先IPv6服务器主机保证既有IPv4地址,又有IPv6地址. 1. IPv4客户端通过getaddrinfo函数,找到服务器端的IPv4地址,然后进行连接. 2. 来自客户端的IPv4

Unix网络编程学习笔记之第4章 基于TCP套接字编程

1. socket函数 int socket(int family, int type,int protocol) 成返回一个套接字描述符.错误返回-1 其中family指定协议族,一般IPv4为AF_INET, IPv6为AF_INET6. 其中type指定套接字类型,字节流:SOCK_STREAM.   数据报:SOCK_DGRAM. 一般情况下通过family和type的组合都可以唯一确定一个套接字类型.所以一般我们就把protocol设为0就可以了. 有时在某些特殊情况下,family和