socket是套接字,通过套接字,进行网络数据的收和发
套接字就像网络中的“手机”
既然是文件,那么理所当然的,我们可以使用文件描述符引用套接字。与管道类似的,Linux 系统将其封装成文件的目的是为了统一接口,使得读写套接字和读写文件的操作一致。区别是管道主要应用于本地进程间通信,而套接字多应用于网络进程间数据的传递。
主机字节序列和网络字节序列
大端序 小端序
地址格式
一个地址标识一个特定通信域的套接字端点, 地址格式与这个特定的通信域相关。 为使不同格式地址能够传入到套接字函数, 地址会被强制转换成一个通用的地址结构sockaddr:
在1Pv4因特网域(AF_INET)中, 套接字地址用结构sockaddr_in表示:
注意, 尽管sockaddr_in 与sockaddr_in6 结构相差比较大, 但它们均被强制 转换成 sockaddr结构输入到套接字例程中
14 字节的 sa_data 根本无法容纳多数协议族的地址值。因此,Linux 定义了下面这个新的通用的 socket 地址结构体,这个结构体不仅提供了足够大的空间用于存放地址值,而且是内存对齐的
#include <bits/socket.h>
struct sockaddr_storage
{
sa_family_t sa_family;
unsigned long int __ss_align;
char __ss_padding[ 128 - sizeof(__ss_align) ];
};
typedef unsigned short int sa_family_t;
专用 socket 地址
*
sin_family: 地址族 AF_INET
sin_port: 端口号,需要用网络字节序表示
sin_addr: IPV4 地址结构:s_addr 以网络字节序表示 IPV4 地址
*/
struct in_addr
{
u_int32_t s_addr;
};
struct sockaddr_in//IPV4
{
sa_family_t sin_family;
u_int16_t sin_port;
struct in_addr sin_addr;
};
struct in6_addr
{
unsigned char sa_addr[16]; // IPV6 地址,要用网络字节序表示 };
struct sockaddr_in6
{
sa_family_t sin6_family; // 地址族:AF_INET6
u_inet16_t sin6_port; // 端口号:用网络字节序表示
u_int32_t sin6_flowinfo; // 流信息,应设置为 0
struct in6_addr sin6_addr; // IPV6 地址结构体
u_int32_t sin6_scope_id; // scope ID,尚处于试验阶段
};