1、What's socket?
socket可以看做用户进程与操作系统内核网络协议栈的编程接口。TCP/IP协议部分已经被内核给实现了,用户只需要实现应用层,这部分程序工作在用户空间。用户空间的程序需要通过套接字来访问内核网络协议栈。
套接字属于全双工的通信,可以用于本机进程间通信,也可以用于网络上不同主机之间的通信。
套接字还可以实现 异构系统 之间的通信,也就是说在不同的设备、不同的操作系统间进行通信。
2、IPV4套接字接口结构
套接字的地址结构用于连接两个端系统,例如双发通信的电话号码一样,我们可以通过 man 7 ip 来查询相对应的结构体。
ipV4套接字结构体:
1 struct sockaddr_in { 2 sa_family_t sin_family; /* address family: AF_INET(IPV4协议) */ 3 in_port_t sin_port; /* port in network byte order(端口号,2byte) */ 4 struct in_addr sin_addr; /* internet address 4byte*/ 5 }; 6 7 /* Internet address. */ 8 struct in_addr { 9 uint32_t s_addr; /* address in network byte order */ 10 };
通用地址结构,可以用于任何协议的socket编程
1 struct sockaddr{ 2 3 uint8_t sin_len; //整个sockaddr结构大小 4 5 sa_family sin_family; //指定地址家族 6 7 char sa_data[14]; // 由sin_family决定它的形式 8 9 };
3、网络字节序
字节序可以分为大端字节序以及小端字节序:
- 大端字节序:最高有效位位于最低内存地址处,最低有效位位于最高地址处
- 小端字节序:最低有效位位于最低内存地址处,最高有效位位于最高地址处
可以通过如图说明:
需要注意:在进行字节传输时,应该使用同一字节序,称为网络字节序。网络字节序采用大端字节序。如果主机为小端字节序,那么传输时需要将小端字节序转换为网络字节序。
4、字节序转换函数:
1 #include <arpa/inet.h> 2 3 uint32_t htonl(uint32_t hostlong); 4 5 uint16_t htons(uint16_t hostshort); 6 7 uint32_t ntohl(uint32_t netlong); 8 9 uint16_t ntohs(uint16_t netshort);
其中:h代表host,n代表network,s代表short,l代表long
描述:
- htonl()函数将无符号整数hostlong从主机字节序转换成网络字节序。
- htons()函数将无符号短整型hostshort从主机字节序转换成网络字节序。
- ntohl()函数功能与 htonl()函数相反
- ntohs()函数功能与htons()函数相反
5、字节转换函数
通常我们看到的ip地址都是点分十进制,程序一般处理的都是32位的地址,因此需要函数在点分十进制与32位地址这两种形式之间的转换
1 #include <sys/socket.h> 2 #include <netinet/in.h> 3 #include <arpa/inet.h> 4 5 in_addr_t inet_addr(const char *cp);//将点分十进制IP地址转换为32位ip 6 7 char *inet_ntoa(struct in_addr in);//将32位ip地址转换为点分十进制
6、套接字类型
套接字类型主要有三种:
- 流方套接字(SOCK_STREAM):它对应TCP协议,它提供面向连接的、可靠的数据传输服务,数据无差错、无重复的发送,且按发送顺序接收。
- 数据报套接字(SOCK_DGREAM):提供无连接服务。不提供无错保证,数据可能丢失或重复,并且接收顺序混乱。
- 原始套接字(SOCK_RAW):它提供一种能力,让我们直接跨越传输层,直接对IP层进行数据封装,通过该套接字,我们可以直接将数据封装成IP层能够认识的协议格式。
参考:https://www.cnblogs.com/QG-whz/p/5426634.html