一、概述
咳咳,首先看了概述我们应该就能明确这一章的重点了:
1.套接字地址结构
这个结构可以在【进程<---->内核】两个方向上传递
2.地址转换函数
用于【文本表达<---->二进制值(存放于套接字地址结构中)】的转换
**注意协议无关性(毕竟IPv4和IPv6这两个协议是不同的,【废话…】)
二、套接字地址结构
1.IPv4套接字地址结构
##IPv4地址和TCP或UDP端口号在套接字地址结构中总以网络字节序存储
##32位IP地址的两种访问方法:
serv.sin_addr(按结构访问)
serv.sin_addr.s_addr(按in_addr_t类型访问)
##套接字地址结构仅在给定主机上使用,结构本身不在主机之间传递
2.通用套接字地址结构
套接字地址结构作为参数传递给套接字函数时,总是以引用形式(即指针)来传递。这样套接字函数就必须处理来自n多协议族的套接字地址结构。
UNIX中定义了一个通用套接字地址结构struct sockaddr,替代这个参数。实际调用中,需要强制类型转换。
3.IPv6套接字地址结构
4.新的通用套接字地址结构
5.套接字地址结构的比较
三、值-结果参数
当向一个套接字函数传递一个套接字地址结构时,传递的是指向该结构的一个指针。该结构的长度也作为一个参数来传递,不过其传递方式取决于结构的传递方向,是进程->内核还是内核->进程。
- 进程—>内核:bind,connect,sendto。
传递参数:结构、结构的整数大小(长度值)
struct sockaddr_in serv;
/* fill in serv{} */
connect (sockfd, (SA *) &serv, sizeof(serv));
- 内核—>进程:accept,recvfrom,getsockname,getpeername
传递参数:结构、指向表示该结构大小的整数变量的指针
struct sockaddr_un cli; /* Unix domain */
socklen_t len;
len = sizeof(cli); /* len is a value */
getpeername(unixfd, (SA *) &cli, &len);
/* len may have changed */
四、字节排序函数
内存中存储字节有两种方法:小端字节序、大端字节序
网络协议必须指定一个网络字节序。主机字节序和网络字节序的转换函数如下:
五、字节操纵函数
名字以b开头(表示字节)的函数【源于BSD4.2】
名字以mem开头(表示内存)的函数【源于ANSI C】
六、inet_aton,inet_addr,inet_ntoa函数
地址转换函数:ASCII字符串<---->网络字节序的二进制值(存放在套接字地址结构中)
inet_aton,inet_addr,inet_ntoa:点分十进制字符串<---->32位网络字节序的二进制IPv4地址
inet_pton,inet_ntop:适用于IPv4和IPv6
七、inet_pton和inet_ntop函数
n:numeric(数值)
p:presentation(表达)
【想到NP之类的请去面壁…】
地址的表达格式通常为ASCII字符串,数值格式则是存放到套接字地址结构中的二进制值
总结:
八、sock_ntop和相关函数
Inet_ntop的一个基本问题:不是协议无关的,要求调用者知道某个套接字结构的格式和地址族。
所以,为了解决这个问题,本书自行编写了sock_ntop函数,它以指向某个套接字地址结构的指针为参数,查看该结构的内部,然后调用适当的函数返回该地址的表达格式。
九、readn、writen和readline函数
TCP套接字为应用进程提供了一个字节流,它们没有记录标记。从TCP套接字read的返回值可能比我们请求的数量少,但是这不表示发生了错误。为帮助读或写一个字节流,本书开发了readn、writen、readline这三个函数。对于文本行交互的应用来说,程序应该按照操作缓冲而非按照操作文本行来编写。
【吐槽】嗯,我不知道自己还能坚持多久...慢慢地事情变得多起来,好像这一周的空闲时间不如上一周多了...必修课的复习我已经两天没有完成既定计划了,然后项目组那边也开始催命了...鉴于我之前各种弃坑的行为,我是多么希望我能够坚持一件事情啊~第三期花了四个晚上学习,节奏还是可以接受的。接下来我觉得还是加大上机的时间,毕竟编程这种东西光靠纸上谈兵是不会有什么进步的。好吧,我去面壁了,突然想到算法作业还没做...