笔记整理,参考见本链接


:star2:三次握手

tcp3


:star2:四次挥手

tcp4


:star2:实现流程

clientServerPythonTCP


:star2:客户端代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# socket简单编写:服务端    客户端
#服务端
import socket # 导入 socket模块
serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# socket.AF_INET :表示基于网络
# socket.SOCK_STREAM:表示基于TCP协议
serv.bind(("127.0.0.1", 8000))
# bind(ip地址,端口号---》元祖的形式):绑定在那个计算机上作为服务器
serv.listen(5)
# listen(n):表示同时接待5个链接,n:控制backlog、即:半链接池;
conn, addr = serv.accept()
# serv.accept():表示接收到客户端的请求信息,
# 此时,服务端会收到:一个tcp链接、客户端ip地址,以元祖形式
#--------------上面完成三次握手---------------------------
msg = conn.recv(1024)
#conn.recv(1024):从链接中接受客户端发的内容,1024表示大小
print("客户的请求信息:", msg)
conn.send(msg.upper())
#收到客户的请求信息内容后,send:再回复客户端一个内容,内容不一定是msg.upper()
#这里只是简单举例
#--------------上面完成数据传输-----------------------------
conn.close()
#关闭链接
serv.close()
#关闭服务

:star:服务端代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# socket简单编写:服务端    客户端
#客户端
import socket# 导入 socket模块
client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# socket.AF_INET :表示基于网络
# socket.SOCK_STREAM:表示基于TCP协议
client.connect(("127.0.0.1",8000))
#connect((服务器的IP,端口号)):表示连接服务器
#--------------上面完成三次握手---------------------------
client.send("hello".encode("utf-8"))
#连接上服务器后,send():向服务器发送,内容必须是二进制
data=client.recv(1024)
#recv(1024)客户端接受服务端回复的内容
#--------------上面完成数据传输-----------------------------
print(data)

:star2:Close 假象

四次挥手没有在python中体现的原因,参考别人的回答:

背景
工作中自己用python写了一个tcp工具,然后用while循环一直接收消息,并且打印出来。然后正常close发现设备并没有离线,然后用了临时的规避方案,发现其实是一直阻塞在recv()接收方法里面,只要传输一条协议,让recv()吃到消息即可正常运行while来让其break退出,但是这种规避方式是临时的,治病要治其根,所以对现在socket进行了研究。
问题原因
虽然已经将连接close掉了,但是client端仍然可以顺利的接收到消息,而且,如果client端发送数据的间隔小于超时时间的话,此连接可以顺利的一直使用,这样,close貌似就一点儿效果都没有了。然后下面是官方解释

close()releases the resource associated with a connection but does not necessarily close the connection immediately. If you want to close the connection in a timely fashion, callshutdown() beforeclose().

大体意思是:close方法可以释放一个连接的资源,但是不是立即释放,如果想立即释放,那么请在close之前使用shutdown方法


:star2:参考