三次握手原理
TCP协议在传输之前会进行三次沟通,一般称为“三次握手”
第一次握手:客户端此时的状态为SYN_SENT,客户端会先向服务器发送 序号为seq=x的SYN =1请求,说‘我想连接到服务器,可不可以’;
第二次握手:服务器收到后,此时的状态由原来的监听状态LISTEN变为SYN_RCVD,对客户端发送的请求作出回应,返回了ACK=x+1(在原序号基础上加1,表示是对这个序号的回应),同时发出了一个序号为seq=y的SYN =1请求,说‘你想连接我,可以啊,那么我可以连接你吗’;
第三次握手:客户端收到服务器的回应加请求后,此时的状态为ESTABLISHED,对服务器发送的请求作出回应,返回了ACK=y+1,说‘你也想连接我啊,可以啊,那么我们两个就连接起来了’,服务器收到客户端的同意后,状态为ESTABLISHED。此时,在客户端与服务端之间是有两条链接的,一条是服务端到客户端,还有客户端到服务端,就如两个城市之间的高速公路一样都是单项;
四次挥手
客户端与服务端连接要经历三次握手,然后断开连接要经历4次挥手
第一次挥手:客户端此时的状态为FIN_WIAT_1,客户端会先向服务器发送序号为seq=x的FIN+ACK 请求,说‘我现在不想和你连接了,我想断开’,此时客户端到服务器的数据是已经发送完了;
第二次挥手:服务器收到后,此时的状态为CLOSE_WAIT,对客户端的请求作出回应,返回了ACK=x+1,说‘我知道了’;
客户端收到服务器的回应后,此时的状态为FIN_WIAT_2,没有任何操作。
第三次挥手:但此时的服务端可能还有数据没有发送完,所以不会与ACK同时发送,只有等到数据都发送完了,才会发送序号为seq=y的FIN请求,说‘那么我们就拜拜,再见了您’
第四次挥手:客户端收到服务器的请求后,此时的状态为TIME_WIAT,对服务器发送的请求作出回应,返回了ACK=y+1,说‘你也想和我断开啊,那么我们两个就分开吧’。此时就彻底断开连接了
Socket
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
模拟一个存在本地的服务器与客户端
服务器
import socket IP='192.168.13.118' PORT=8989 ADDRESS=(IP,PORT) BUFFSIZE=1024 client={'192.168.13.131':'姚晓锋','192.168.13.235':'盛琪良'} #1.买手机,是用来接收链接请求,从而建立链接的 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #2.插手机卡,设置服务端的IP地址与端口 phone.bind(ADDRESS) #3.开机,开启监视功能,链接池最大容量为5 phone.listen(5) #4.等待电话请求,等待客户端的请求 while True: conn,client_addr=phone.accept() # 5.收发消息 data=conn.recv(BUFFSIZE) print('%s:'%client[client_addr[0]],data.decode('utf-8')) #返回给客户端的信息 conn.send('我是你爸爸'.encode('utf-8')) #6.挂电话链接 conn.close()
客户端
import socket IP='192.168.13.118' PORT=8989 ADDRESS=(IP,PORT) BUFFSIZE=1024 #1.买手机 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #2.拨号,连接服务器的IP,端口 phone.connect(ADDRESS) #3.发收消息 phone.send('我一进来就看见常威在。。。'.encode('utf-8'))#只能发送bytes类型的 data=phone.recv(BUFFSIZE) print('服务器返回的信息:',data.decode('utf-8')) #4.挂电话链接 phone.close()