socket是套接字,通过套接字,进行网络数据的收和发
套接字就像网络中的“手机”

既然是文件,那么理所当然的,我们可以使用文件描述符引用套接字。与管道类似的,Linux 系统将其封装成文件的目的是为了统一接口,使得读写套接字和读写文件的操作一致。区别是管道主要应用于本地进程间通信,而套接字多应用于网络进程间数据的传递。

socket通信基础_地址格式

主机字节序列和网络字节序列

大端序  小端序

地址格式

一个地址标识一个特定通信域的套接字端点, 地址格式与这个特定的通信域相关。 为使不同格式地址能够传入到套接字函数, 地址会被强制转换成一个通用的地址结构sockaddr:

 在1Pv4因特网域(AF_INET)中, 套接字地址用结构sockaddr_in表示:

socket通信基础_套接字_02

注意, 尽管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,尚处于试验阶段
	};