loop本地回环:
Loop本地回环,通常指的是以127开头的IP地址段(127.0.0.1 -- 127.255.255.254),其中127.0.0.1是最常用的一个地址,被称为本地回环地址(Loop back address)。这个地址不属于任何一个有类别地址类,它代表设备的本地虚拟接口,因此默认被看作是永远不会宕掉的接口。在Windows操作系统中也有相似的定义,所以在不安装网卡前就可以ping通这个本地回环地址。
Loop本地回环的主要作用包括:
-
测试本机的网络配置:通过ping 127.0.0.1,可以检查本机的网卡和IP协议安装是否正常。如果能成功ping通,说明本机的网络配置基本没有问题。
-
应用程序的资源调用:在某些SERVER/CLIENT的应用程序运行时,需要调用服务器上的资源。当这些程序在同一台机器上运行而没有别的SERVER时,可以把SERVER的资源装在本机,SERVER的IP地址设为127.0.0.1,这样程序也可以正常运行。
粘包问题:
粘包问题是TCP/IP通信中常见的一个问题,主要源于TCP的流式传输特性。在TCP协议中,数据是以流(stream)的形式传输的,这种流数据没有明确的数据开始和结尾边界,因此容易出现粘包现象。具体来说,当发送方连续发送多个数据包时,由于TCP的缓冲机制,这些数据包可能会被合并成一个大的数据包发送给接收方,或者在接收方由于接收缓冲区的原因,多个数据包被合并在一起处理,这就是粘包现象。
粘包问题的原因主要有两个方面:
- 发送方原因:TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一包数据。若连续几次发送的数据都很少,TCP会根据优化算法把这些数据合成一包后一次发送出去,这样接收方就收到了粘包数据。
- 接收方原因:接收方用户进程不及时接收数据,导致多个数据包在接收方的缓冲区中粘连在一起,当后续数据到达时,这些数据包被一起处理,从而产生粘包现象。
粘包问题的解决方法:
- 使用特定结束符 :
- 在每个数据包的末尾添加特定的结束符(如换行符\n),接收方在接收到数据时,根据结束符来区分数据包的边界。这种方法实现简单,但需要注意避免数据包内容中出现与结束符相同的字符,否则可能会导致误判。
- 固定数据大小 :
- 发送方和接收方约定每个数据包的大小,当发送的数据不足约定大小时,用空字符或其他填充字符补齐。这种方法简单但不够灵活,且会增加额外的网络传输负担。
- 封装自定义数据协议 :
- 在TCP协议的基础上封装一层自定义数据协议,该协议中包括数据头和数据体两部分。数据头中存储了数据体的大小等信息,接收方在接收到数据后,先解析数据头,根据数据头中的信息来提取数据体,从而避免粘包问题。这种方法实现起来相对复杂,但灵活性高,适用于多种场景。
recv函数和send函数:
recv函数
recv函数的主要功能是从已连接的套接字接收数据。
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
参数:
- sockfd/socket:套接字描述符/socket对象,用于标识要接收数据的套接字。
- buf:指向缓冲区的指针/缓冲区,用于存储接收到的数据。在C语言中,它是一个void类型的指针。
- len:缓冲区长度/bufsize,指定接收数据的最大字节数。如果接收到的数据大于这个长度,则多余的数据将被丢弃;如果小于这个长度,则实际接收到的数据将被存储在缓冲区中。
- flags(可选):用于指定接收数据的额外选项。一般设置为0,常见的选项包括MSG_WAITALL(等待所有数据到达)和MSG_DONTWAIT(非阻塞模式)等。
返回值
- 成功时,
recv
返回接收到的字节数。如果连接被正常关闭,则返回 0。 - 如果发生错误,则返回 -1,并设置相应的 errno 以指示错误的类型。
注意事项
recv
函数是阻塞的,这意味着如果套接字上没有数据可读,调用recv
的线程或进程将被挂起,直到数据到达或发生错误。- 可以通过设置套接字为非阻塞模式或使用 select/poll/epoll 等机制来避免阻塞。
- 在实际应用中,由于网络延迟、拥塞等原因,
recv
可能无法一次性接收到发送方发送的全部数据。因此,通常需要编写循环来不断接收数据,直到达到期望的数据量或遇到特定的结束标志。 - 接收到的数据可能不会以发送时的形式完全呈现,因为 TCP/IP 协议栈可能会对数据进行分片或重新排序。因此,在接收端,可能需要对数据进行重组或解析。
send函数:
用于实现数据的发送功能。
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
参数:
sockfd
:套接字描述符,一个指向已打开套接字的引用,该套接字已连接到远端地址。buf
:指向要发送数据的缓冲区的指针。len
:指定要发送的数据的字节数。flags
:发送操作的控制标志。对于大多数应用程序,这个参数被设置为 0,但在某些情况下,可以指定特定的标志来修改send
的行为。
返回值
- 成功时,
send
函数返回实际发送的字节数。这个数可能小于请求发送的字节数,尤其是在非阻塞套接字上或者发送缓冲区已满时。 - 如果发送过程中出现错误,
send
函数返回 -1,并设置相应的 errno 以指示错误的类型。
注意事项
send
函数在大多数情况下是阻塞的,即如果发送缓冲区已满,调用send
的线程或进程将被挂起,直到发送缓冲区中有足够的空间可以容纳要发送的数据或发生错误。- 可以通过设置套接字为非阻塞模式或使用 select/poll/epoll 等机制来避免阻塞。
- 在 TCP/IP 协议中,发送的数据可能会被分成多个数据包进行传输,并且这些数据包可能会以不同的顺序到达接收端。但是,TCP 协议保证了数据的完整性和顺序性,即接收端将按照发送的顺序接收并重新组装这些数据包。
- 由于网络延迟、拥塞等原因,
send
函数可能无法立即发送所有数据。因此,在需要发送大量数据时,可能需要编写循环来不断发送数据,直到所有数据都被发送完毕。 - 在某些情况下,如发送非阻塞套接字上的数据时,
send
函数可能返回小于请求发送的字节数的值,表示只有部分数据被发送。此时,应用程序需要处理这种情况,通常是通过再次调用send
函数来发送剩余的数据。
TCP协议特点:
1,面向连接 : TCP在传输数据之前,必须先建立连接,即进行三次握手,以确保双方都已准备好进行数据交换。连接建立后,双方才能开始通信。
2,可靠传输 : TCP通过一系列机制(如确认应答、超时重传、错误检测等)确保数据的可靠传输。如果数据在传输过程中发生错误或丢失,TCP会重新发送数据,直到数据被正确接收为止。 **3,基于字节流 :**TCP不保留报文边界,将应用程序交下来的数据视为一个字节流进行传输。
UDP协议特点:
**1,无连接 :**UDP在传输数据之前不需要建立连接,发送方只需将数据打包成UDP数据报并发送出去即可。这种无连接的特性使得UDP的通信过程更加简单、快速。
**2,不可靠 :**UDP不保证数据的可靠传输,它只负责将数据报发送出去,而不关心数据是否到达接收方。如果数据在传输过程中发生错误或丢失,UDP不会进行重传或错误恢复。
**3,基于数据报:**UDP保留了报文边界,即发送方发送的每个数据报在接收方都会作为一个独立的单元进行处理。这使得UDP非常适合于传输那些对实时性要求较高且对丢包不敏感的数据。
常用的网络测试工具:
wires hark抓包工具:
TCP首部结构
**TCP(传输控制协议)**的首部是TCP协议数据包中的一个关键部分,它包含了用于传输控制的各种重要信息。TCP虽然是面向字节流的,但其传送的数据单元是报文段,一个TCP报文段分为首部和数据两部分。以下是对TCP首部主要字段的详细解析:
1. 固定部分(前20个字节)
- 源端口(Source Port):占2个字节,用于标识发送该TCP报文段的应用进程的端口号。
- 目的端口(Destination Port):占2个字节,用于标识接收该TCP报文段的应用进程的端口号。
- 序号(Sequence Number):占4个字节,用于标识发送方发送的数据段。序号范围是[0, 232 - 1],序号增加到232-1后,下一个序号就回到0。TCP是面向字节流的,在一个TCP连接中传送的字节流中的每一个字节都按顺序编号。
- 确认号(Acknowledgment Number):占4个字节,是期望收到对方下一个报文段的第一个数据字节的序号。例如,如果B正确收到了A发送的一个序号为501、长度为200字节的报文段,那么B期望收到的下一个数据序号是701,于是B在发送给A的确认报文段中把确认号置为701。
- 数据偏移(Data Offset):占4位,它指出TCP报文段的数据起始处距离TCP报文段的起始处有多远(以32位字即4字节为计算单位)。这个字段实际上是指出TCP报文段的首部长度,其最大值为15(即60字节),这也是TCP首部的最大长度。
- 保留(Reserved):占6位,保留为今后使用,但目前应置为0。
- 控制位(Control Bits) :共6位,用于说明本报文段的性质,包括确认ACK、推送PSH、复位RST、同步SYN、终止FIN等。
- ACK:仅当ACK=1时确认号字段才有效,TCP规定,在连接建立后所有传送的报文段都必须把ACK置为1。
- PSH:当两个应用进程进行交互式的通信时,TCP可以使用推送操作,发送方TCP把PSH置1,并立即创建一个报文段发送出去。
- RST:当RST=1时,表明TCP连接中出现严重差错,必须释放连接,然后再重新建立运输连接。
- SYN:在连接建立时用来同步序号,当SYN=1而ACK=0时,表明这是一个连接请求报文段。
- FIN:用来释放一个连接,当FIN=1时,表明此报文段的发送方的数据已发送完毕,并要求释放运输连接。
- 窗口(Window):占2字节,窗口值是[0, 2^16-1]之间的整数,窗口指的是发送本报文段的一方的接收窗口(而不是自己的发送窗口)。窗口值告诉对方,从本报文段首部中的确认号算起,接收方目前允许对方发送的数据量(以字节为单位)。
- 检验和(Checksum):占2字节,用于检查数据的完整性和正确性,其检验的范围包括首部和数据这两部分。
- 紧急指针(Urgent Pointer):占2字节,紧急指针仅在URG=1时才有意义,它指出本报文段中的紧急数据的字节数(紧急数据结束后就是普通数据)。
2. 可选部分
TCP报文段首部后面还可以有4n字节(n为整数)的可选字段,这些字段是根据需要而增加的,用于支持TCP的各种扩展功能。
三次握手
四次挥手