写在前面
昨天的初识PythonSocket大概讲了下Python Socket
的知识,觉得不是很深入(其实这篇也只是个皮毛对知识的一个总结), 觉得理解Socket的原理对自己还是挺有帮助的. 对于 Web 的原理对于为什么 RESTful
为什么会成为Api接口的公认形式的理解还是非常有帮助.在深入之前我们还是首先要理解一些术语
.
Socket
网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket
A socket is an endpoint for communication between two machines.
是的,从名字上我们可以知道 Socket
一个管道中两端的末端。试想网络通信好比一个水管,而 Socket
就是入水口(发送方)或是出水口(接收方). 那么既然只是两个端点她就不会在乎中间经过的媒介是什么,是水管(直连),是游泳池(局域网),是城市管网(城域网),是世界地下水系统(Internet)的方式都无所谓了.
协议(protocol)
又称为通信协议
是对数据格式和计算机之间交换数据时必须遵守的规则的正式描述
a communication protocol is a system of rules that allow two or more entities of a communications system to transmit information via any kind of variation of a physical quantity.
Socket支持 TCP
以及 UDP
. 这里就不扩展开来了.
Server
服务端,一个用于等待客户端请求
以及服务和处理
客户端请求的并响应
的一端
Client
客户端, 是这个服务
的另外一端. 用于发送请求
.
What we are building 我们将要做什么
我们将要简单的实现一个服务端和一个客户端。 服务端开启了一个Socket
端口等待客户端的链接。一旦客户端连接上了,她可以发送一些信息。同时,服务端可以处理(在这里就只是简单的转换为大写)客户端发送过来的信息再返还回客户端.这是很简单感觉但也很直白说明的一种实现方式,基本上都是 等待响应 -> 发送信息 -> 处理信息 -> 返回信息
这样即完成了一次通信.下面我们先来看看代码的实现其实就是昨天的service代码
以及今天新增的client代码
, 然后在讲讲她们的实现过程.
创建两个文件
- server.py
- client.py
server.py
1 | import socket |
下面我们来看看上面的服务端代码做了什么
- 首先我们导入了Python的Socket库
- 接着我们定义了
main
函数 - 我们定义了两个变量
host
以及port
用于保存服务端接受数据的IP地址和端口,这里是本地网所以往往就是127.0.0.1
,5000
端口只是我随意选择的一个如果你自己也可以随意选择一个另外的,只是这里需要注意一下必须是超过1024的端口号,因为<=1024是系统预留的,不然会引起不必要的麻烦比如23 24 53 80 8080这些等等. - 之后我们定义了一个变量
mySocket
, 这是Python socket的一个实例 - 在服务端我们必须要绑定IP地址和端口号,调用的方法是
.bind()
. 这里需要注意的是.bind()
接受的是一个Tuple. 因此我用了双括号
. 其实你也可以写成address = ("127.0.0.1", 5000)
然后直接传入.bind
也可以。上面的写法更便于理解而已. - 接下来我们调用了
.listen()
并且给了个1
给她,意思就是开始持续地监听上面我们绑定的IP地址下面的5000
端口直到我们关闭连接. - 一切都设置好了,那么我们怎么知道
Who
发送过来的What
呢,我们就定义了两个变量conn连接
和addr地址
用来保存这两个东西. - While 循环中就是server代码的核心了. 我们知道连接已经建立起来的那么久设置了一个
while True
的循环用于等待接收接下来client.py
发送过来的信息,但这个过程当中连接状态是没有关闭的. 我们申明了一个变量data
用于接收客户端发送过来的数据并且解码了它, 这里非常注意在Python3中使用的是decode
而不是str()
来转换buffer的数据了..rect(1024)
中的1024是缓存接受到数据的一个大小. - 接下来把接收到的data进行处理, 判断是否为空 转换大小写 打印接收到的数据等等 内部的一些操作. 之后把加工完的数据在
.encode()
之后通过.send()
返回给客户端. - 直到我们的客户端不再发送信息过来的时候我们就调用
.close()
来关闭这个连接了。或者自己关闭服务端的运行.
client.py
1 | import socket |
我们来看看客户端做了些什么, 和服务端很差不多其相似的地方就简单带过。
- 导入socket库,申明变量用于存放IP地址、端口、Socket实例等
- 不同于server端需要的是
.bind()
绑定,客户端需要的是.connect()
连接, 这里注意地址和端口都是服务端的。很容易理解,你要写信给别人就需要填写对方的收信地址和收件人。 - 接下来就是等待我们出入需要发送的信息,直到输入的内容是
q
就关闭这个连接, 同时由于服务端收到了关闭连接的状态,也会关闭这个connection
Let’s runing it
Server
1 | > python3 server.py |
Client
1 | > python3 client.py |
EOF.