apue是在太无聊了。。。。我只能转unp,缓解一下
所以什么叫协议栈 就是七层模型,看上去像是一个栈
局域网 LAN(Local Area Network)
广域网 WAN(Wide Area Network),最大的广域网是Internet
tar --help | head -n 10
返回输出的前10行: head -n 10,最后10行 tail -n 10
解压zip文件
unzip 要解压的文件 -d 你的目录
环境配置参考:UNP学习第一步:unp.h的安装及第一个程序的运行_Owen Wei的博客-CSDN博客
netstat 网络状态查询命令
-i i代表interface,网络接口(其实就是网卡)的信息
-r 代表router
root@ubun2004:/home/learnUnp/unpv13e-master# netstat -i
Kernel Interface table
Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg
ens33 1500 152378 0 0 0 15102 0 0 0 BMRU
lo 65536 3256 0 0 0 3256 0 0 0 LRU
root@ubun2004:/home/learnUnp/unpv13e-master# netstat -nr
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 192.168.113.2 0.0.0.0 UG 0 0 0 ens33
169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 ens33
192.168.113.0 0.0.0.0 255.255.255.0 U 0 0 0 ens33
其中 lo代表loopback,就是环回地址,ens33,在书里面是eth0,代表以太网
如果要看某个网络接口的详细信息,就用
ifconfig lo
结果如下:
root@ubun2004:/home/learnUnp/unpv13e-master# ifconfig ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.113.128 netmask 255.255.255.0 broadcast 192.168.113.255
inet6 fe80::4adf:fdef:5ccf:bbab prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:eb:d2:7f txqueuelen 1000 (Ethernet)
RX packets 152566 bytes 200079002 (200.0 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 15182 bytes 1374154 (1.3 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
root@ubun2004:/home/learnUnp/unpv13e-master# ifconfig lo
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 3276 bytes 312034 (312.0 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 3276 bytes 312034 (312.0 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
找到局域网内其他主机的方法,ping 广播地址
看到 2.10 没看下去了
套接字分为监听(LISTEN)套接字和连接(CONNECTED)套接字,一开始服务端只有监听套接字,当有客服请求服务器时,通过fork创建连接套接字,套接字由4个元素确认,源、目的地址,源、目的端口
2.11.1 TCP输出
每个TCP套接字有一个发送缓冲区,SO_SNDBUF用来更改缓冲区的大小
3.2 套接字机构地址
3.2.1 IPv4套接字地址结构
in应该是INET的缩写 iNet代指一切支持IP协议的网络 inet_百度百科
3.2.2 通用套接字地址结构
以及bind函数
3.2.3 IPv6套接字地址结构
3.2.5 套接字地址结构的比较![](https://i-blog.csdnimg.cn/blog_migrate/4e66fb5d3d465c798c4e6fad36174ded.png)
3.3 值-结果参数
4.2 socket函数
TCP套接字建立和读写的过程
各种socket常量:
4.3 connect函数
TCP客户通过connect来与服务端建立连接,由connect激发的TCP三次握手
sockfd是套接字描述符,类似于文件描述符, servaddr是套接字的服务端地址结构体,addrlen代表结构体大小
4.4 bind函数
就是把一个本地协议地址(例: localhost:80)赋予一个套接字
后面没看
第五章 TCP客户/服务器程序示例
主要是客户端和服务端的main函数,以及str_echo和str_cli,具体还没运行
看到了5.6, 5.5看了
第六章 I/O 以及select、poll
阻塞和非阻塞,就一个轮询差别,更高级的是多路复用,以及异步I/O (asynchronous I/O,AIO)
非阻塞和异步的区别在于,非阻塞会多次系统调用,而异步I/O(AIO)是只有一次系统调用,并且数据复制完才会返回给程序处理(不太清楚AIO和DMA的关系)
看到6.3, 6.3没看
第七章 套接字选项
前面都没看
7.13 fcntl 函数
跟file control有关,fcntl用来对描述符进行操作,比如设置该描述符为阻塞型
设置非阻塞时,要先F_GETFL获取当前socket的属性值,再通过或运算,F_SETFL设置属性值
第十一章 名字与地址转换
11.1 概述
11.2 域名系统
11.2.1 资源记录(Resource Record,RR)
A是IPv4地址,AAAA是IPv6地址,MX是把一个主机作为"邮件交换器"
11.2.2 解析器和名字服务器
emm 所以解析器是用来decode_qname和encode_qname的? MIT的xv6的encode:
static void
encode_qname(char *qn, char *host)
{
char *l = host;
for(char *c = host; c < host+strlen(host)+1; c++) {
if(*c == '.') {
*qn++ = (char) (c-l);
for(char *d = l; d < c; d++) {
*qn++ = *d;
}
l = c+1; // skip .
}
}
*qn = '\0';
}
看这个样子是,把.号去掉了,其他的都保留?
关于htons和htonl,其实就是本地字节地址转网络字节地址,会有大端和小端的区别,s就是short,l就是long,参见
static inline uint16 bswaps(uint16 val)
{
return (((val & 0x00ffU) << 8) |
((val & 0xff00U) >> 8));
}
static inline uint32 bswapl(uint32 val)
{
return (((val & 0x000000ffUL) << 24) |
((val & 0x0000ff00UL) << 8) |
((val & 0x00ff0000UL) >> 8) |
((val & 0xff000000UL) >> 24));
}
// Use these macros to convert network bytes to the native byte order.
// Note that Risc-V uses little endian while network order is big endian.
#define ntohs bswaps
#define ntohl bswapl
#define htons bswaps
#define htonl bswapl
并且在xv6系统中,有这样一个dns请求结构体:
struct dns_question {
uint16 qtype;
uint16 qclass;
} __attribute__((packed));
然后我们随便截取一个DNS包,发现下面的数据
其中的type A, class IN是啥呢,在 11.2.1 资源记录 那一节有个A,就是对应这里的type A,代表是一个IPv4的地址,IN代表的是internet
在xv6中dns的结构体是:
struct dns {
uint16 id; // request ID
uint8 rd: 1; // recursion desired
uint8 tc: 1; // truncated
uint8 aa: 1; // authoritive
uint8 opcode: 4;
uint8 qr: 1; // query/response
uint8 rcode: 4; // response code
uint8 cd: 1; // checking disabled
uint8 ad: 1; // authenticated data
uint8 z: 1;
uint8 ra: 1; // recursion available
uint16 qdcount; // number of question entries
uint16 ancount; // number of resource records in answer section
uint16 nscount; // number of NS resource records in authority section
uint16 arcount; // number of resource records in additional records
} __attribute__((packed));
上面id对应的应该是Transaction id,rd就是recursion desired,还有opcode啥的
上面只是Transaction ID和Flags两部分,还有一部分是
也就分别对应了qdcount,ancount,nscount,arcount
Question 就是你要问哪个域名的地址,比如这个request里面就是ssl.qq.com的
而Authority RRs,其实RR就是资源记录(Resource Record)的简称,代表有几条记录,比如下面的Anser RRs:2,而Answers里面的确有两条记录
11.2.3 DNS替代方法
不使用DNS协议,可以通过访问静态主机文件,/etc/hosts也即hosts文件
11.3 gethostbyname和gethostbyaddr
gethostbyname 把主机名映射为IPv4
gethostbyaddr 把IPv4映射为主机名
返回的hostent结构体如下:
hostent运行以后如下
其中的address就是上面的h_addr_list
11.5 getservbyname和getservbyport
通常来说,一个service对应一个端口,两者的对应关系,储存在/etc/services中
domain 53/tcp # Domain Name Server
domain 53/udp
http 80/tcp www # WorldWideWeb HTTP
可以看出,dns的tcp和udp用的是同一个端口
第一个参数是服务名,右边的是协议名,比如下面调用的就是dns的udp,第四个失败是因为ftp只支持tcp
同一端口,协议不同,服务也会不同
root@ubun2004:/home/learnUnp/unpv13e-master/names# grep 514 /etc/services
shell 514/tcp cmd syslog # no passwords used
syslog 514/udp