1.主机字节序和网络字节序
主机字节序指的是CPU或操作系统本身使用的字节序。它决定了数据在内存中的存储顺序。
(1)主机字节序分为大端字节序和小端字节序
大端字节序:高位字节(MSB, Most Significant Byte)存放在内存的低地址处,低位字节(LSB, Least Significant Byte)存放在内存的高地址处。例如,一个4字节的数据0x12345678
在大端字节序中的存储顺序为:12 34 56 78
(从低地址到高地址)。
小端字节序:与大端字节序相反,低位字节存放在内存的低地址处,高位字节存放在内存的高地址处。
大多数个人电脑和工作站采用小端字节序,而一些网络上的服务器则可能采用大端字节序。
(2)网络字节序(Network Byte Order)
网络字节序采用大端字节序(Big Endian)作为标准。这意味着在网络传输中,高位字节先被发送,低位字节后被发送。
网络字节序和主机字节序之间的转换主要靠以下函数
2.atoi()
在C++(以及C语言)中,atoi()
是一个标准库函数,用于将字符串(const char*
类型)转换为整数(int
类型)。这个函数是定义在 <cstdlib>
(在C语言中是 <stdlib.h>
)头文件中的。
atoi()
的名称来源于 "ASCII to integer" 的缩写,但实际上它更准确地被描述为 "字符串到整数" 的转换。
3.data()
返回string字符串的指针
4.accept()
在之前的文章中我介绍了accept()函数的写法为以下所示
struct sockaddr_in c_addr;
socklen_t c_size=sizeof(struct sockaddr_in);
int c_fd=accept(socket_fd,(struct sockaddr *)&c_addr,&c_size);
string clientip=inet_ntoa(c_addr.sin_addr);//将客户端ip从网络字节序转换成字符串
但是实际上第二个参数和第三个参数可以为空(表示不关心客户端的ip端口信息)
int c_fd=accept(server_fd,0,0);
5.fork()
fork()
函数的主要作用是创建一个新的进程,这个新进程是原进程的副本(通常称为子进程)。在 Unix 和类 Unix 系统中(如 Linux),fork()
是一个非常重要的系统调用,它允许程序通过复制自身来创建并发执行的分支。
(1)进程间通信
由于父进程和子进程是两个独立的进程,它们有各自的地址空间,因此需要通过某种形式的进程间通信(IPC)机制来交换信息。常见的 IPC 机制包括管道(pipe)、消息队列(message queue)、信号(signal)、共享内存(shared memory)等。
(2)返回值
fork()
在父进程中返回新创建的子进程的进程 ID(PID),这是一个非零的正整数。在子进程中,fork()
返回 0。如果 fork()
调用失败,它将返回 -1,并设置全局变量 errno
以指示错误原因。
(3)执行路径分离
在 fork()
调用之后,父进程和子进程可以执行不同的代码路径。这通常通过在 fork()
之后使用条件语句(如 if
语句)来实现,根据 fork()
的返回值判断当前是父进程还是子进程,并执行相应的代码。
6.TIME_WAIT
TIME_WAIT是TCP连接关闭过程中的一种状态,它存在于TCP四次挥手的过程中,特别是在主动关闭连接的一方(通常是客户端,但也可以是服务器)发送FIN报文并收到对方的ACK确认后,进入TIME_WAIT状态。
TIME_WAIT的作用
(1)可靠的终止TCP连接
(2)保证让迟来的TCP报文段有足够的时间被识别并丢弃
TIME_WAIT状态会占用一个本地端口,直到该状态结束。如果TIME_WAIT状态过多,会导致端口资源紧张,进而影响新连接的建立。
7.netstat -na(查看网络连接状态)
8.TCP缓存
客户端和服务端在接收发送数据时会有个接收缓冲区和发送缓冲区
假设客户端已经在服务端的监听(listen)队列中但是还没有accept,这时让客户端发送一段数据给服务端,再将客户端的socket close(),服务端再accept(),那么服务端还能接收到客户端的数据吗?
答案是可以的,因为服务端监听的客户端和它发送的数据都已经再服务端的接收缓冲区了
既然又缓冲区,那么缓冲区就一定会有大小,我们知道send()/write()一般是不阻塞的,recv()/read()一般是阻塞的,但是如果发送方的接收缓冲区满了或者接收方的接收缓冲区满了,那么send()/write()也会阻塞
9.Nagle算法和Ack延时
(1)Nagle算法
Nagle算法,全称为John Nagle提出的Nagle算法,是一种用于减少网络传输中的小包数量,以减少网络拥塞,从而提高网络效率的算法,它主要应用于TCP协议中。
实现:当缓存的数据量达到一定程度或达到最大延迟时间时,再统一发送。
关闭:TCP协议提供了TCP_NODELAY选项,允许应用程序禁用Nagle算法,以牺牲带宽效率为代价,换取更低的延迟。
(2)Ack延时
是TCP协议中的一种机制,用于减少ACK消息的数量,从而提高网络效率
延时发送:当TCP接收到数据时,会启动一个定时器(时延通常为200ms),等待是否有数据一起发送。如果在定时器到期前有数据需要发送,则ACK会随数据一起发送。
立即发送:
- 如果有响应数据需要发送,ACK会随响应数据立即发送。
- 如果在等待发送ACK期间,接收到了第二个或更多的数据包,则会立即发送ACK。
Nagle算法和Delayed ACK同时使用时,可能会出现死锁情况,造成网络延时