学习目标
mindmap
root((学习目标))
1.什么是socket
2.IPv4套接口地址结构
3.网终字节序
4.字节序转换函数
5.地址转换函数
6.套接字类型
1. 什么是socket
- socket可以看成是用户进程与内核网络协议栈的 编程接口
- socket不仅可以用于本机的进程间通信,还可以 用于网络上不同主机的进程间通信
我的理解: socket就是对前面学习的tcp/ip的代码封装,但是位于系统的内核,也就是说提供给用户的一组API,用于网络通信.
warning
socket 这里理解成"插座"
mindmap
root((socket需要的属性))
地址: sockaddr_in
sin_addr
sin_port
sin_family
ipv4 socket 地址结构体
ipv4 socket地址结构体,在头文件netinet/in.h中定义。 sockaddr_in结构体定义如下:
使用man 7 ip命令查看sockaddr_in结构体的定义:
struct sockaddr_in {
sa_family_t sin_family; // 地址族,ipv4 就是AF_INET
in_port_t sin_port; // 端口号
struct in_addr sin_addr; // IP地址
char sin_zero[8]; // 未使用,注意这个在man 7 ip中没有说明
//暗示程序员不需要知道这个??
//当成上面的普通的来用?
};
sin_family字段表示地址族,socket在设计的时候还可以用于其它的协议,不仅是tcp/ip,比如还有unix域,对于IPv4地址,该值为AF_INET。sin_port字段表示端口号,使用网络字节序(big-endian)存储。sin_addr字段表示IP地址,使用struct in_addr结构体表示。
struct in_addr结构体定义如下:
struct in_addr {
uint32_t s_addr; // IP地址,使用网络字节序存储
};
s_addr字段表示IP地址,使用网络字节序存储。
疑问1
note
到这里就有一个疑问,socketaddr_in结构体具体的定义是什么呢?后面有没有char sin_zero[8];字段呢?通过下面的代码来验证
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
int main (int argc, char *argv[]) {
printf("size bytes of sockaddr_in %ld\n",sizeof(struct sockaddr_in));
printf("size bytes of sin_family %ld\n",sizeof(sa_family_t));
printf("size bytes of sin_port %ld\n",sizeof(in_port_t));
printf("size bytes of sin_addr %ld\n",sizeof(struct in_addr));
return 0;
}
输出的结果是:16,
size bytes of sockaddr_in 16
size bytes of sin_family 2
size bytes of sin_port 2
size bytes of sin_addr 4
结果确实是少8
通用套接字地址结构体sockaddr
定义如下:
它适用于任何地址协议,
struct sockaddr {
sa_family_t sa_family; // 地址族
char sa_data[14]; // 地址数据,长度取决于地址族
};
sa_family字段表示地址族。sa_data字段表示地址数据,长度取决于地址族。
#include <stdio.h>
#include <netinet/in.h>
int main(int argc, char const *argv[])
{
struct sockaddr_in addr1;
struct sockaddr addr2;
printf("sizof(sockaddr_in) = %ld\n", sizeof(addr1));
printf("sizof(sockaddr) = %ld\n", sizeof(addr2));
// 最后输出的结果是:
// sizof(sockaddr_in) = 16
// sizof(sockaddr) = 16
// 说明sockaddr_in和sockaddr的大小是相同的,都是16字节。
return 0;
}
在通常的网络编程中,我们先填写sockaddr_in结构体,然后再把它转换成通用的sockaddr结构体.
网络字节序
网络字节序
字节序分为:
- 大端字节序(Big-endian)
- 小端字节序(Little-endian)

网络字节序(Network Byte Order)是指数据的高位字节保存在内存的低地址中,而数据的低位字节保存在内存的高地址中。就是大端字节序.
在TCP/IP协议中,所有长度字段和数字都采用网络字节序。例如,在TCP报文头部的源端口字段中,端口号的高位字节保存在内存的低地址中,而端口号的低位字节保存在内存的高地址中。