【计算机网络基础知识】

首先举一个生活化的例子,当你和朋友打电话时,你可能会使用三次握手和四次挥手的过程进行类比:

三次握手(Three-Way Handshake):

  1. 你打电话给朋友:你首先拨打你朋友的电话号码并等待他接听。这就像客户端向服务器发送一个连接请求。

  2. 朋友接听电话:如果你朋友接听了电话,他会告诉你:“喂,我在这里!”这表示你的连接请求已经被接受。这就像服务器发送一个确认消息给客户端。

  3. 你确认朋友的回答:在你确认朋友在电话线的另一端时,你会说:“好的,我听到了!”这表示你已经知道连接已经建立了。这就是客户端再次向服务器发送一个确认消息。

思考:为什么要三次握手呢,有人说两次握手就好了

举例:已失效的连接请求报文段。

client发送了第一个连接的请求报文,但是由于网络不好,这个请求没有立即到达服务端,而是在某个网络节点中滞留了,直到某个时间才到达server,本来这已经是一个失效的报文,但是server端接收到这个请求报文后,还是会想client发出确认的报文,表示同意连接。

假如不采用三次握手,那么只要server发出确认,新的建立就连接了,但其实这个请求是失效的请求,client是不会理睬server的确认信息,也不会向服务端发送确认的请求,但是server认为新的连接已经建立起来了,并一直等待client发来数据,这样,server的很多资源就没白白浪费掉了,采用三次握手就是为了防止这种情况的发生,server会因为收不到确认的报文,就知道client并没有建立连接。这就是三次握手的作用。

四次挥手(Four-Way Handshake):

  1. 通话结束:当你和朋友的谈话结束时,你会说:“好的,我得挂了。”这就像客户端发送一个关闭连接的请求给服务器。

  2. 朋友确认挂断:你的朋友会回答:“好的,再见!”这表示服务器已经收到了关闭连接的请求,并且也准备好关闭连接。但是他仍然会等待任何未处理的数据。这是服务器发送一个确认关闭的消息给客户端。

  3. 朋友准备好了:一旦你的朋友处理了所有数据,他会再次说:“好的,现在我也准备好了,我们断开连接吧!”这就像服务器发送一个关闭连接的请求给客户端。

  4. 确认断开连接:你会回答:“好的,再见!”这表示客户端收到了服务器的关闭请求,并且也准备好关闭连接。这就是客户端发送一个确认关闭的消息给服务器。

思考:那么为什么是4次挥手呢?

为了确保数据能够完成传输。

关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。

可能有人会有疑问,tcp我握手的时候为何ACK(确认)和SYN(建立连接)是一起发送。挥手的时候为什么是分开的时候发送呢?

因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭 SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步挥手。

思考:客户端突然挂掉了怎么办?

思考:客户端突然挂掉了怎么办?

正常连接时,客户端突然挂掉了,如果没有措施处理这种情况,那么就会出现客户端和服务器端出现长时期的空闲。解决办法是在服务器端设置保活计时器,每当服务器收到客户端的消息,就将计时器复位。超时时间通常设置为2小时。

若服务器超过2小时没收到客户的信息,他就发送探测报文段。若发送了10个探测报文段,每一个相隔75秒,还没有响应就认为客户端出了故障,因而终止该连接。

1.详细讲一下TCP的三次握手与四次挥手

三次握手(Three-Way Handshake)

  1. 第一步:客户端发送 SYN 请求

    • 客户端向服务器发送一个SYN(同步)标志位的数据包,表明客户端想要建立连接。该数据包中还包含客户端的初始序列号(Sequence Number)。
  2. 第二步:服务器确认 SYN 请求

    • 服务器收到客户端发送的SYN请求后,会发送一个SYN-ACK(同步-确认)标志位的数据包作为响应。这个数据包中的SYN标志位表示服务器接收到了客户端的SYN请求,ACK标志位表示服务器同意建立连接,并在确认号(Acknowledgment Number)字段中回复客户端的初始序列号+1,同时也会发送自己的初始序列号。
  3. 第三步:客户端确认 SYN-ACK

    • 客户端收到服务器的SYN-ACK响应后,会发送一个确认数据包,其中ACK标志位置为1,表示客户端确认收到了服务器的响应。同时,客户端会将确认号设置为服务器初始序列号+1。

完成这个过程后,TCP连接就建立起来了,双方可以开始进行数据传输。

四次挥手(Four-Way Handshake)

  1. 第一步:客户端发送关闭连接请求

    • 当客户端决定关闭连接时,会发送一个FIN(结束)标志位的数据包给服务器,表示客户端不再有数据要发送了,但仍可以接收数据。
  2. 第二步:服务器确认关闭请求

    • 服务器收到客户端的FIN后,会发送一个ACK确认数据包,表明服务器收到了关闭请求。服务器在这个响应中可能还会包含一些剩余数据,如果有的话。
  3. 第三步:服务器发送关闭请求

    • 当服务器也准备好关闭连接时,会发送一个FIN标志位的数据包给客户端,表明服务器不再有数据要发送了。
  4. 第四步:客户端确认关闭请求

    • 客户端收到服务器的FIN后,会发送一个ACK确认数据包给服务器,表明客户端收到了关闭请求。然后等待一段时间,确保服务器收到了这个确认,最后关闭连接。

完成这个过程后,TCP连接就彻底关闭了,双方不再进行数据传输。

2.为什么是三次握手不是两次呢,为什么是四次挥手不是三次呢?

为什么是三次握手而不是两次?

  • 第一次握手(SYN):客户端向服务器发送连接请求,并指明初始序列号。
  • 第二次握手(SYN + ACK):服务器收到请求后,确认连接请求,并发送自己的序列号。
  • 第三次握手(ACK):客户端收到服务器的确认后,也发送确认消息,表示连接已建立。

三次握手的设计是为了解决可能出现的两种情况:重复连接请求和延迟的连接请求。通过三次握手,确保了双方的状态都同步了,建立了可靠的连接。

为什么是四次挥手而不是三次?

  • 第一次挥手(FIN):客户端发送关闭连接请求。
  • 第二次挥手(ACK):服务器收到关闭请求后,发送确认消息。
  • 第三次挥手(FIN):服务器在关闭连接之前,先发送关闭连接请求。
  • 第四次挥手(ACK):客户端收到服务器的关闭请求后,发送确认消息,完成连接的关闭。

四次挥手的设计是为了确保双方都能够知道连接已经关闭,避免出现半关闭状态,即其中一方已经关闭了连接,而另一方还在发送数据的情况。

     TCP建立连接要进行3次握手,而断开连接要进行4次,这是由于TCP的半关闭造成的,因为TCP连接是全双工的(数据可在两个方向上同时传递)。所以进行关闭时每个方向上都要单独进行关闭,这个单方向的关闭就叫半关闭。关闭的方法是一方完成它的数据传输后,就发送一个FIN来向另一方通告将要终止这个方向的连接,收到这个FIN表示这个方向上再没有数据流动,但是收到FIN的那一端仍然可以发送数据。但在发生这个过程以后,服务端可能需要继续发送数据(这个阶段是close_wait),在服务端也确保需要关闭的时候,服务端再发送FIN,尝试去关闭。

3.get和post的区别,分别适用于什么场景?

一、TCP不会丢数据

TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。TCP通过一系列机制来确保数据的可靠传输,包括:

  1. 序列号:TCP给每个数据包分配一个序列号,确保接收方能够按照正确的顺序接收并重组数据包。
  2. 确认应答:接收方在接收到数据包后会回复一个确认消息(ACK),表示已经成功接收到数据,并且确认下一个期望接收的数据包序号。
  3. 超时重传:如果发送方在一定时间内没有收到接收方的确认消息,就会认为数据包丢失,并重新发送该数据包。

这些机制共同作用,使得TCP在大多数情况下能够确保数据的可靠传输,即不会丢数据。

二、TCP可能会粘包

然而,关于“粘包”的问题,这实际上是TCP字节流特性的一种表现,而不是TCP本身的一个错误或问题。TCP是一个面向字节流的协议,它并不保留消息的边界。当发送方连续发送多个数据包时,这些数据包在TCP看来只是一串连续的字节流。接收方在接收这些字节流时,可能无法准确地按照发送方的数据包边界来接收,这就可能导致所谓的“粘包”现象。

解决TCP粘包问题的方法通常包括:

  1. 固定长度:发送方每次发送固定长度的数据包,接收方按照固定长度来接收数据。
  2. 特殊标记:在数据包的末尾添加特殊标记(如换行符、回车符等),接收方根据这些标记来分割数据包。
  3. 长度字段:在每个数据包的头部添加一个表示数据长度的字段,接收方根据这个字段来确定每个数据包的大小。

总结

get()请求是一种 HTTP 方法,用于从服务器检索数据。它将请求的数据附加在 URL 后面,以查询字符串的形式出现。特点:

  • 安全性和隐私性较低,因为请求数据暴露在 URL 中。
  • 数据量有限制,通常不超过 2KB。
  • 适合请求无状态的操作,如页面跳转、检索数据等。

post()请求是一种 HTTP 方法,用于向服务器发送数据。它将数据存储在请求体中,不会出现在 URL 中。特点:

  • 安全性和隐私性较高,因为数据不暴露在 URL 中。
  • 数据量较大,没有大小限制。
  • 适合请求有状态的操作,如表单提交、上传文件等。

适用场景

(1)GET 请求适用于:

数据检索:如查询数据库记录。

页面跳转:如导航到其他页面。

无状态操作:如天气预报、新闻检索等。

(2)POST 请求适用于:

数据提交:如表单提交、上传文件。

数据创建:如添加新记录到数据库。

有状态操作:如购物车结算、用户登录等。

无状态操作和有状态操作的区别

  • 无状态操作:指的是每次请求都是独立的,不依赖于之前的状态。服务器处理请求时,不会考虑之前的请求或会话信息。这使得无状态操作易于扩展和维护,因为服务器不需要存储任何会话信息。GET请求通常用于无状态操作。
  • 有状态操作:指的是请求可能会改变服务器的状态,或者依赖于之前的请求或会话信息。有状态操作通常需要服务器存储一些信息,比如用户的会话状态或事务状态。POST请求通常用于有状态操作。

深入理解


1.GET 和 POST都是http请求方式, 底层都是 TCP/IP协议;通常GET 产生一个 TCP 数据包;POST 产生两个 TCP 数据包(但firefox是发送一个数据包),

2.对于 GET 方式的请求,浏览器会把 http header 和 data 一并发送出去,服务器响应 200
(返回数据)表示成功;

而对于 POST,浏览器先发送 header,服务器响应 100, 浏览器再继续发送 data,服
务器响应 200 (返回数据)。

套接字是什么

套接字(socket)

首先,套接字可以理解为是一套代码库和接口层。它是对网络中不同主机间进程间通信端点的抽象。套接字提供了端到端的通信服务,允许位于不同主机上的两个进程之间进行数据交换

通过网络通信的每对进程需要使用一对套接字。不同的进程之间的通信所使用的套接字是不一样的,套接字可以用来区分不同的进程之间的数据传输。套接字主要有目标IP、传输层使用的传输协议、传输层使用的端口号这3个重要参数。

套接字(Socket)大致位于OSI模型的会话层、TCP/IP模型的应用层,每一台机器都有一个套接字,可以想象成套接字是机器的端口,他们之间都有一条虚拟的电缆,电缆的每一段都插入到套接字中,也就是说一台机器上的套接字可以和另一台机器上的套接字组成一条通信通道,我们可以用这个通道在两台机器之间发送数据。

基于TCP协议的服务器和客户端Socket通信流程的详细步骤:
 

服务器端流程

  1. 创建Socket

    • 服务器端首先调用socket()函数创建一个Socket,该函数返回一个文件描述符,用于后续的通信操作。在创建时,需要指定地址族(如AF_INET表示IPv4)、套接字类型(如SOCK_STREAM表示TCP协议)和协议(通常为0,表示自动选择协议)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值