字节序转换接口

发布时间 2023-09-10 20:42:43作者: 若达萨罗

第一组

#include <arpa/inet.h>
	// 函数作用:将无符号整数hostlong从主机字节顺序转换为网络字节顺序。
	uint32_t htonl(uint32_t hostlong);
	// 函数作用:将无符号短整数hostshort从主机字节顺序转换为网络字节顺序。
	uint16_t htons(uint16_t hostshort);
	// 函数作用::将无符号整数netlong从网络字节顺序转换为主机字节顺序。
	uint32_t ntohl(uint32_t netlong);
	// 函数作用:将无符号短整数netshort从网络字节顺序转换为主机字节顺序。
	uint16_t ntohs(uint16_t netshort);
	// 说明:h代表主机host   n代表网络
	// network   s------->端口号short     l-------->IP地址
	// 返回值:成功返回要转换的字节序  失败返回-1
	// 适用范围在不同主机之间进行网络通信,如果是本机的各个程序之间就不需要转换,直接写端口和地址

第二组

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
	// 功能:inet_aton()函数用于将点分十进制IP地址转换成网络字节序IP地址;
	// 返回值:如果这个函数成功,函数的返回值非零,如果输入地址不正确则会返回零;
	int inet_aton(const char *cp, struct in_addr *inp);
	// 功能:inet_addr()函数用于将点分十进制IP地址转换成网络字节序IP地址;
	// 返回值:如果正确执行将返回一个无符号长整数型数。如果传入的字符串不是一个合法的IP地址,将返回INADDR_NONE;
	in_addr_t inet_addr(const char *cp);

	in_addr_t inet_network(const char *cp);
	// 功能:inet_ntoa()函数用于网络字节序IP转化点分十进制IP;
	// 返回值:若无错误发生,inet_ntoa()返回一个字符指针。否则的话,返回NULL。其中的数据应在下一个WINDOWS套接口调用前复制出来;
	char *inet_ntoa(struct in_addr in);

	struct in_addr inet_makeaddr(in_addr_t net, in_addr_t host);

服务器编程中四种性能IO模型

  1. 阻塞IO

    • read(), recv(), recvfrom()
      这些函数本身是不具有阻塞属性,而是文件描述符的本身阻塞属性导致这个函数执行所表现出来的属性是阻塞
      在默认情况下,Linux下建立的socket套接字都是阻塞的
  2. 非阻塞情况IO

    • 给文件描述符添加非阻塞属性
      由于非阻塞属性,所有不断询问套接字中是否有数据到达
  3. 多路复用(重点掌握

    • 同时对多个IO口进行造作(也就是同时监听多个套接字)
      可以在规定时间内监测数据是否到达
  4. 信号驱动

    • 异步驱动
      当socket中有数据到达时,通过发送信号告知用户

阻塞IO

  • 读阻塞:当数据缓冲区中没有数据可以读取时,调用read,recv,recvfrom就会无限阻塞
  • 写阻塞:当缓冲区剩余的大小小于写入的数据量,就会发生写阻塞,知道缓冲区中的数据被读取

非阻塞IO

1.阻塞与非阻塞的差异
阻塞IO的流程
建立套接字(阻塞)------>读取了数据------>判断缓冲区中还有没有数据
------>如果没有数据------>进入无限等待------>直到有数据为止
------>如果有数据就读取数据------>进入无限等待------>直到有数据为止

非阻塞IO的流程
建立套接字(阻塞)------>将套接字设置为非阻塞属性-------->读取了数据------>判断缓冲区中还有没有数据?
------>如果没有数据------>读取失败------->接口马上返回,不会一直阻塞
------>如果有数据就读取数据------>接口也会返回

  1. 如何给文件描述符设置非阻塞属性
#include <unistd.h>
#include <fcntl.h>

	int fcntl(
		int fd,   // 参数1:文件描述符
		int cmd,   // 参数2:请求命令
		... /* arg */    // 参数3:填不填取决的第二个参数
	);
	// 第二个参数:F_GETFL(void)------>读取文件描述符的状态,第三个参数忽略
	//            F_SETFL(int)------->设置文件描述符的状态,第三个参数要填
	// 注意:O_CREAT,O_EXCL,0_NOCTTY,O_TRUNC----这些状态是不可以用fcntl去设置
	// O_APPEND, O_ASYNC,O_DIRECT,O_NONBLOCK,O_NOATIME这些状态是可以被设置的
	// 追加   信号触发模式   不使用缓冲区写入
	// O_NOATIME:不更新文件的修改时间
	// O_NONBLOCK:非阻塞属性
int fd = open("...", ...);
int status = fcntl(fd, F_GETFL);
status |= O_NONBLOCK;
fcntl(fd, F_SETFL, status);