Linux网络编程——详解SOCKET

一、预备知识大端模式、小端模式

  • 大端字节序(Big Endian):最高有效位存于最低内存地址处 , 最低有效位存于最高内存处;
  • 小端字节序(Little Endian):最高有效位存于最高内存地址 , 最低有效位存于最低内存处 。

Linux网络编程——详解SOCKET文章插图
网络字节序
  • 我们已经知道 , 内存中的多字节数据相对于内存地址有大端和小端之分 , 磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分 。 网络数据流同样有大端小端之分 , 也就是说,当接收端收到第一个字节的时候,它将这个字节作为高位字节还是低位字节处理
  • 网络数据流的地址应这样规定:先发出的数据是低地址 , 后发出的数据是高地址
  • TCP/IP协议规定:把接收到的第一个字节当作高位字节看待 , 因此网络数据流应采用大端字节序 , 即低地址高字节
可以调用以下库函数做网络字节序和主机字节序的转换#include //这些函数调用成功后返回处理后的值 , 调用失败则返回-1uint32_t htonl(uint32_t hostlong); //主机字节顺序转换为网络字节顺序 对无符号长型进行操作4bytesuint16_t htons(uint16_t hostshort); //主机字节顺序转换为网络字节顺序 对无符号短型进行操作2bytesuint32_t ntohl(uint32_t netlong);//网络字节顺序转换为主机字节顺序 对无符号长型进行操作4bytesuint16_t ntohs(uint16_t netshort);//网络字节顺序转换为主机字节顺序 对无符号短型进行操作2bytesIP地址转换函数
  • Linux提供了用于将点分十进制表示的IP地址与二进制表示的IP地址相互转换的函数族
早期
#include #include #include //数字加点类型 转换成 将32位的IPIP地址存放在参数straddr中 , 返回结果存放在addrptr中 int inet_aton(const char *straddr, struct in_addr *addrptr);//将32位的IP 转换成 数字加点类型char *inet_ntoa(struct in_addr straddr);//数字加点类型 转换成 将32位的IPin_addr_t inet_addr(const char *cp);/*只能处理IPv4的ip地址不可重入函数注意参数是struct in_addr*/现在
#include int inet_pton(int af, const char *src, void *dst);const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);/*支持IPv4和IPv6可重入函数*/Linuxc/c++服务器开发高阶视频 , 电子书学习资料后台私信【架构】获取
Linux网络编程——详解SOCKET文章插图
Linux网络编程——详解SOCKET文章插图
sockaddr数据结构
  • Linux中定义了一种通用的套接字结构类型strcut sockaddr , 以供不同的协议调用
  • strcut sockaddr 很多网络编程函数诞生早于IPv4协议 , 那时候都使用的是sockaddr结构体,为了向前兼容 , 现在sockaddr退化成了(void *)的作用 , 传递一个地址给函数 , 至于这个地址类型是sockaddr_in还是sockaddr_in6(文章没有列举出) , 由地址族确定 , 然后函数内部再强制类型转化为所需的地址类型
#include struct sockaddr { unsigned short sa_family; /* address族, AF_xxx */ char sa_data[14];/* 14 bytes的协议地址 */};参数sa_family可选择如下
  • AF_INET IPv4协议
  • AF_INET6 IPv6协议
  • AF_LOCAL UNIX协议
  • AF_LINK 链路地址协议
  • AF_KEY 密钥套接字
除了sockaddr以外 , Linux中还定义了另外一种结构类型sockaddr_in , 它和sockaddr等效且可以互相转换(需要显式转换) , 通常在涉及TCP/IP的编程协议中使用
#include struct sockaddr_in { short int sin_family;/* Internet地址族 */ unsigned short int sin_port;/* 端口号 */ struct in_addr sin_addr;/* Internet地址 */ unsigned char sin_zero[8];/* 添0(和struct sockaddr一样大小)*/};//其中in_addr由于历史设计原因导致结构体多余struct in_addr{__be32 s_addr;//32位IPv4地址 , 网络字节序};网络设计模式c/s 客户端/服务器
  • 需要开发客户端服务器 , 采用自定义协议
  • 必须先下载客户端 , 数据提前缓冲好
  • 需要考虑安全问题
  • 开发工作量大
b/s web/服务器
  • 不需要安装软件 , 点击浏览器就可以看到
  • 工作量小 , 客户端基本浏览器方式
  • 缺点:必须遵循http协议 , 动态加载数据
二、SOCKET概述
  • linux中的网络编程通过socket接口实现 。 socket既是一种特殊的IO , 它也是一种文件描述符
socket可以简单理解成为一个插座和插排 , 那么如何匹配?
Linux网络编程——详解SOCKET文章插图