1.什么是TCP/IP协议?它由哪些协议组成?
TCP/IP协议是互联网上最常见的协议之一,它是一组通信协议的集合,包括传输控制协议(TCP)、互联网协议(IP)以及其他相关协议。TCP/IP协议是互联网上数据传输的基础,几乎所有的网络应用都依赖于它。
TCP/IP协议由以下几个协议组成:
- IP协议(Internet Protocol):IP协议是TCP/IP协议中最核心的协议,它负责将数据包从源地址传输到目的地址。IP协议是一种无连接的协议,它不保证数据包的可靠传输,也不保证数据包的顺序。
- TCP协议(Transmission Control Protocol):TCP协议是一种面向连接的协议,它提供可靠的数据传输服务。TCP协议负责将数据分割成小的数据段,保证数据的可靠传输,还能够控制数据的流量和处理网络拥塞。
- UDP协议(User Datagram Protocol):UDP协议是一种无连接的协议,它不保证数据的可靠传输和顺序,但是它的传输速度比TCP协议快。
- ARP协议(Address Resolution Protocol):ARP协议负责将IP地址转换成物理地址,以便数据包能够在网络上正确传输。
- ICMP协议(Internet Control Message Protocol):ICMP协议是一种网络管理协议,它用于传递网络错误和状态信息,例如ping命令就是通过ICMP协议实现的。
- DNS协议(Domain Name System):DNS协议用于将域名解析成IP地址,以便数据包能够正确传输。
- FTP协议(File Transfer Protocol):FTP协议是一种文件传输协议,它用于在网络上传输文件。
除了上述的协议外,还有许多其他的协议,如HTTP协议、SMTP协议、POP协议等等,它们都是基于TCP/IP协议的,用于实现不同的网络应用和服务。
2.什么是三次握手四次挥手
TCP连接是指在TCP/IP协议中,建立起两个网络应用程序之间的通信连接。TCP连接提供了可靠的数据传输,可以保证数据的完整性和顺序性。TCP连接的建立和断开过程如下:
2.1.建立连接(三次握手)
TCP连接的建立过程是通过三次握手(Three-way Handshake)来完成的。具体过程如下:
- 第一步:客户端向服务器发送一个SYN包,表示请求建立连接。SYN包中会携带一个随机生成的序列号(Seq)。
- 第二步:服务器收到SYN包后,向客户端发送一个SYN+ACK包,表示确认建立连接。SYN+ACK包中会携带一个确认号(Ack),该确认号等于客户端的序列号加1,同时也会携带一个随机生成的序列号。
- 第三步:客户端收到服务器的SYN+ACK包后,向服务器发送一个ACK包,表示确认建立连接。ACK包中的确认号等于服务器的序列号加1。
第 2 次握手传回了 ACK,为什么还要传回 SYN?
- 服务端传回发送端所发送的 ACK 是为了告诉客户端:“我接收到的信息确实就是你所发送的信号了”,这表明从客户端到服务端的通信是正常的。回传 SYN 则是为了建立并确认从服务端到客户端的通信。
2.2.三次握手各自出现问题,会发生什么结果?
第一次握手出现问题:第一个包,即A发给B的SYN 中途被丢,没有到达B
客户端发送SYN请求连接报文,如果迟迟等不到服务器的请求确认报文段,那么就会进行超时重传,具体重传几次,要看tcp_syn_retries内核参数,一般默认是5次。要注意的是,重传的请求连接报文的seq序列号字段还是之前的seq,不会重新生成。
第二次握手出现问题:第二个包,即B发给A的SYN +ACK 中途被丢,没有到达A
服务器发送的第二次握手是连接确认报文段,既包括对第一次握手的ACK确认,同时还有SYN字段表示要建立连接,所以第二次握手也可以成为SYN-ACK报文。所以当第二次握手丢失,客户端迟迟等不到第一次握手的确认,就会触发超时重传机制,进行超时重传;服务器等不到自己SYN连接的确认,也会进行超时重传。客户端和服务器具体的超时重传次数还是由内核参数决定。
第三次握手出现问题:第三个包,即A发给B的ACK 中途被丢,没有到达B
服务器得不到ACK报文,但是ACK报文丢失,ACK 报文是不会有重传的,当 ACK 丢失了,就由对方重传对应的报文。所以当到达服务器的超时重传时间后,服务器会超时重传第二次报文,当达到最大超时重传次数还没得到ACK报文,服务器就会断开连接。
没有连接时为Active状态
2.3.断开连接(四次挥手)
2.3.1TCP连接的断开过程是通过四次挥手(Four-way Handshake)来完成的。具体过程如下:
- 第一步:客户端向服务器发送一个FIN包,表示请求关闭连接。
- 第二步:服务器收到FIN包后,向客户端发送一个ACK包,表示确认关闭连接。服务器此时仍可向客户端发送数据。
- 第三步:服务器完成数据发送后,向客户端发送一个FIN包,表示请求关闭连接。
- 第四步:客户端收到FIN包后,向服务器发送一个ACK包,表示确认关闭连接。此时TCP连接彻底关闭。
总的来说,TCP连接的建立和断开过程是通过三次握手和四次挥手来完成的。通过这些过程,TCP连接可以提供可靠的数据传输,保证数据的完整性和顺序性,是一种非常重要的网络协议。
2.4.用微信聊天的方式来模拟TCP连接的建立和断开过程
2.4.1TCP连接的建立过程(三次握手):
客户端:你好,我想和你建立连接,你能收到我的消息吗?(发送一个“打招呼”的消息,表示想要建立连接)
服务器:嗯,我收到了你的消息,我也想和你建立连接,你能收到我的回复吗?(回复一个“打招呼”的消息,并询问能否收到)
客户端:是的,我收到了你的回复,我们现在可以开始建立连接了。(回复一个“确认”的消息,表示同意建立连接)
此时,客户端和服务器之间的TCP连接已经建立成功,可以开始进行数据传输了。
2.4.2TCP连接的断开过程(四次挥手):
客户端:我想断开和你的连接了,我不再发送消息了,但我还能接收你的消息。(发送一个“再见”的消息,表示想要断开连接)
服务器:好的,我收到了你的消息,我也不会再发送消息了,但我还能接收你的消息。(回复一个“再见”的消息,表示同意断开连接)
服务器:我已经把所有的消息都发送完了,现在准备关闭连接。(发送一个“好的,我已经发送完消息了”的消息,表示准备关闭连接)
客户端:好的,我收到了你的消息,我也已经把所有的消息都发送完了,现在准备关闭连接。(回复一个“好的,我已经发送完消息了”的消息,表示同意关闭连接)
此时,客户端和服务器之间的TCP连接已经断开成功,不再进行数据传输。
2.5.为什么TCP不是两次握手或四次握手
2.5.1.二次握手的过程:
- A 发送同步信号SYN + A's Initial sequence number
- B发送同步信号SYN+B's Initial sequence number+B's ACK sequence number
这里有个问题,A与B就A的初始序列号达成了一致,假设这里是1000.但是B无法知道A是否已经收到自己的同步信息,如果这个同步信息丢失了,A和B就B的初始序列号将无法方达成一致。
-
两次握手问题:
- 如果只进行两次握手,即客户端发送连接请求,服务器回复确认,看似连接建立了。但这种简化过程存在严重问题:若服务器的确认消息在网络中滞留,客户端会误以为连接已建立,而实际上服务器并未意识到这一连接。这可能导致资源浪费或数据传输异常,因此需要第三次握手确认双方都准备好建立连接。
2.5.2.四次握手过程:
- A发送同步信息SYN+A’s Initial sequence number
- B 确认收到A的同步信号,并记录 A’s ISN 到本地,命名 B’s ACK sequence number
- B发送同步信号SYN + B’s Initial sequence number
- A确认收到B的同步信号,并记录 B’s ISN 到本地,命名 A’s ACK sequence number
很显然2和3 这两个步骤可以合并,只需要三次握手,可以提高连接的速度与效率。文章来源:https://www.toymoban.com/news/detail-861487.html
-
四次握手问题:文章来源地址https://www.toymoban.com/news/detail-861487.html
- 如果采用四次握手,即在断开连接时增加额外的握手步骤,会导致不必要的复杂性和开销。TCP的设计考虑了在关闭连接时需要确保双方都知道对方已准备好断开连接,同时也需要确认数据的完整传输和状态。因此,四次挥手是为了实现这些目标,确保数据的完整性和连接的正常关闭。
3.简单的Java示例
3.1.服务端代码:
import java.io.*;
import java.net.*;
public class TCPServer {
public static void main(String[] args) {
try {
// 创建一个ServerSocket,监听端口9999
ServerSocket serverSocket = new ServerSocket(9999);
// 等待客户端连接
System.out.println("等待客户端连接...");
Socket clientSocket = serverSocket.accept();
System.out.println("客户端已连接");
// 获取输入流
BufferedReader input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
// 读取客户端发送的数据
String inputData = input.readLine();
System.out.println("收到数据: " + inputData);
// 关闭连接
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.2.客户端代码:
import java.io.*;
import java.net.*;
public class TCPClient {
public static void main(String[] args) {
try {
// 连接到服务器
Socket socket = new Socket("localhost", 9999);
// 获取输出流
PrintWriter output = new PrintWriter(socket.getOutputStream(), true);
// 发送数据
String message = "Hello, server!";
System.out.println("发送数据: " + message);
output.println(message);
// 关闭连接
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
到了这里,关于网络协议TCP/IP是什么的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!