Linux高性能服务器编程 读书笔记(1)
第五章 Linux网络编程基础API
字节序
什么是大小端字节序?
这里以32位机举例, 32位机CPU一次可以装载4字节, 那么这4个字节不同的排序方式就对应了不同的字节序 :
- 大端字节序 : 顺着排, 0x12345678 将被排序为 12 34 56 78.
- 小端字节序 : 逆着排, 0x12345678 将被排序为 78 56 34 12.
为什么要分大小端?
其实更多还是因为历史原因, 早期都是按照大端字节序来设计的, 因为顺着排更符合人类的阅读习惯, 早期网络协议设计都是按大端设计的, 并且网络协议一旦实施就不好改了, 所以直到现在网络传输的字节序都是大端字节序, 因此大端字节序又称为网络字节序.
后来人们发现小端字节序更符合CPU的运算逻辑, 使用小段字节序编码可以让CPU运行更加高效, 因此之后的主机大都采用小端字节序, 因此小段字节序又称为主机字节序.
1 |
|
以上为long类型端口从主机字节序转为网络字节序的函数.
Socket
shutdown关闭socket
1 |
|
shoudown类似于进阶版的close, close是直接断开读写, shoudown可以分别关闭读端写端.
howto为选项 :
- SHUT_RD : 只关闭写端.
- SHUT_WR : 只关闭读端.
- SHUT_RDWR : 双端关闭.
应用场景 : 半双工实现, 客户端收到EOF可以直接关闭读端, 写端不关闭可以继续处理没有处理完的事务.
其实就是读端和写端都会占用资源, close只能同时释放, showdown可以根据具体情况选择只读不写/只写不读, 提前释放部分资源.
socket选项
SO_REUSEADDR : 强制使用处于TIME_WAIT状态的连接占用的socket地址.
- TIME_WAIT作用 : TCP连接发送的数据可能滞后, 如果崩溃立即重启, 可能接收到旧数据包造成混乱.
SO_REUSEADDR作用 :
- 可以避免服务器崩溃后进入TIME_WAIT状态, 配合systemd可以实现快速重启服务.
- 支持多个进程同时绑定同一个端口(仅限UDP), 用于视频影音等高并发用多个进程同时处理发送到同一个端口上的信息.
1
2int reuse = 1; // 表示启用设置
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));SO_RCVBUF/SO_SNDBUF : 用于修改TCP发送和接收缓冲区的大小.
缓冲区大小最小为256字节, 大小会按设置的大小的两倍计算.
1
2int bufsize = 2000; // 标定新的缓冲区大小
setsockopt(sockfd, SOL_SOCKET, SO_RCV, &bufsize, sizeof(bufsize))
网络信息API
在现实生活中我们习惯用域名代替IP地址, 用服务名代替端口号, 使用网络信息API便可以实现<域名+服务名>到<IP+port>的双向转化, 便于我们socket等操作的进行. 主要是两大函数getaddrinfo
和getnameinfo
, 这两个函数线程安全并且支持各种地址族和协议类型, 可以使socket进行动态设置以实现动态实时处理与跨平台性.
getaddrinfo
这个函数可以通过主机名获得IP地址, 通过服务名获得端口号.
1 |
|
我们可以利用获取的信息直接建立socket :
1 |
|
getnameinfo
通过socket地址返回主机名/服务名, 和getaddrinfo是相反的作用.
1 |
|
1 |
|