「这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战」。
先前,我们介绍了最基础的TCP连接使用方式:单向的信息传递。只是它的局限性实际上比较大,仅仅只考虑单向的数据流动,对于消费数据的程序来说是比较被动的。它只能接受数据再处理,而很多时候的情况并非如此。
更常见的情况是什么呢,是一种协作式的关系,好比是两个人聊天,我说一些话,你回一些话。两个人是处于平等地位的。回到我们的 TCP 连接中,它也是类似这种情况,如果从经典的 C/S 架构来看,TCP连接程序的中两个主体是同时拥有这两种身份的。
然而,由于网络设计的原因,绝大多数时候,他们不会同时扮演两个身份,更常见的还是一方作为 Server 而另一方作为 Client ,这里面其实有一些哲学原因。
基于这种模型,我们假设这样的一种服务,当收到一段数据之后,服务程序把数据逆序发送回到原来的程序。
那么客户程序要做的事是发送一段数据,然后等待数据返回,程序核心逻辑如下:
while True:
client.send(input().encode())
recv = client.recv(buffer_size)
print('从服务端接受到的数据: ', recv.decode())
考虑服务端接受到请求,然后建立一个连接之后的情况,那么服务端要做的则是把接受到的数据发送给客户端。 核心逻辑如下:
while True:
data = conn.recv(buffer_size)
print('从客户端接受到的数据: ', data)
conn.send(data[::-1])
到这里我们就完成了最基本的所谓的请求回复模型。
现在我们考虑下,如果我们要换一种功能,或者换个说法,我们希望服务端有多个功能,然后客户端可以自行选择使用哪个。
这里就引出了一个新的问题,我们传输的仅仅是数据,如果要实现上述功能,需要的是消息语义。我们需要程序双方明白要做什么。明白了这一点之后,实际实现是比较简单的。
与上述的代码思路类似,不同的是我们要规定一个控制数据的读取方式,当然这里可以自行考量。比如比较简单的方式,在头部加入控制数据。几位或者以某个字符分割。然后服务程序根据控制数据决定操作方式。
最初的 HTTP 协议与这种方式就是类似思路的实现。也就是经典的请求回复模型的实践。不过这种方式实际上是浪费了 TCP 的特性的,它们没能充分的利用 TCP 面向连接,全双工通信的特点。具体的问题和解决方式我们下次再介绍。