网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。
建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API)
主要内容:
- 1.基于TCP协议下的socket通信流程
- 2.基于UDP协议下的socket通信流程
- 3.粘包现象
1.基于TCP协议下的socket通信流程
(1)TCP和UDP的对比
TCP(Transmission Control Protocol)可靠的、面向连接的协议(eg:打电话)、传输效率低全双工通信(发送缓存&接收缓存)、面向字节流。使用TCP的应用:Web浏览器;文件传输程序。
UDP(User Datagram Protocol)不可靠的、无连接的服务,传输效率高(发送前时延小),一对一、一对多、多对一、多对多、面向报文(数据包),尽最大努力服务,无拥塞控制。使用UDP的应用:域名系统 (DNS);视频流;IP语音(VoIP)。
应用层
对应协议:HTTP,SMTP,POP3
对应设备:无
传输层
对应协议:TCP与UDP协议
对应设备:四层交换机,四层的路由器
网络层
对应协议:IP协议
对应设备:路由器,三层交换机
数据链路层
对应协议:arp协议
对应设备:网桥,以太网交换机,网卡
物理层
对象协议:无
对应设备:中继器,集线器,双绞线
3次握手
client syn为1 随机产生seq=j 进入syn_sent
server 收到syn为1 将标志位syn和ACK都置为1 ack=j+1 产生seq=K 进入syn_rcvd状态
client收到后检查ack是不是j+1 如果是将标志位syn和ack都置为1 ack=K+1 双方进established
4次断开
Client发送 fin 进入fin_wait_1状态
Server 收到fin 发送ack 确认序列号+1 close_wait状态 #告诉客户端你先等一下,我看下我的管道里面是否还有信息,如果有给处理完
Server发送一个fin关闭连接 server进入 last_ack状态
Client收到fin后进入 time_wait 发送ack给server server进入closed(刻漏声的)
TCP 和UDP下socket差异对比图
(2) TCP协议下的socket通信流程
具体的通信流程
- 先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。
- 在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。
- 客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束
TCP服务器端
import socket sk = socket.socket() sk.bind(('127.0.0.1',8898)) #把地址绑定到套接字 sk.listen() #监听链接 conn,addr = sk.accept() #接受客户端链接 执行这句,表示建立了3次握手 ret = conn.recv(1024) #接收客户端信息 print(ret) #打印客户端信息 conn.send(b'hi') #向客户端发送信息 conn.close() #关闭客户端套接字 执行这句,表示经历了4次挥手 sk.close() #关闭服务器套接字(可选) 关闭套接字,不在接收客户端请求。 tcp_server.py
TCP 客户端
import socket sk = socket.socket() # 创建客户套接字 sk.connect(('127.0.0.1',8898)) # 尝试连接服务器 sk.send(b'hello!') ret = sk.recv(1024) # 对话(/接收) print(ret) sk.close() # 关闭客户套接字 tcp_client.py
#############udp###################
UDP server 通信
import socket udp_server = socket.socket(type=socket.SOCK_DGRAM) #设置udp方式 ip_port = ('127.0.0.1',8002) udp_server.bind(ip_port)#把地址绑定到套接字 from_client_msg,client_addr = udp_server.recvfrom(1024)#服务器接收服务发来的值 udp_server.sendto(b'fuwuqi',client_addr)#服务器说 发送给客户端 print(from_client_msg,client_addr) #打印服务器说的话 客户端的地址
UDP client 通信
import socket udp_client = socket.socket(type=socket.SOCK_DGRAM)#使用udp方式 ip_port = ('127.0.0.1',8002)##把地址绑定到套接字 udp_client.sendto(b'hello',ip_port)#客户端 向服务器端发动hello ip地址端口 from_server_msg,server_addr = udp_client.recvfrom(1024)#客户端接收服务发来的值 print(from_server_msg,server_addr)#打印出来
################udp while方式+名字#################
####server import socket lst = {'egon': '