目录
1. 单客户端断线可重连
特点:单线程阻塞接收信息,单客户端
原理:
sock_client, address = sock.accept()函数是一个阻塞等待函数,当连接客户端后建立连接,然后进入echo_handler进行while训话与次客户端进行通信连接,然后阻塞等待response = sock.recv(8192)接收信息,当客户端断开后会收到一个空数据,程序break回到echo_server函数中继续sock.accept(),重新接入客户端
# -*- coding: utf-8 -*-
from socket import socket, AF_INET, SOCK_STREAM
def echo_handler(sock, address):
print("Get Connection from address:", address)
while True:
response = sock.recv(8192)
if not response:
break
print(f"Got {response}")
sock.sendall(response)
def echo_server(address, back_log=5):
sock = socket(AF_INET, SOCK_STREAM)
sock.bind(address)
sock.listen(back_log)
while True:
sock_client, address = sock.accept()
echo_handler(sock_client, address)
if __name__ == "__main__":
echo_server(('localhost', 12388))
2. 断线信息包是否粘包问题
2.1 问题思考
普通包发送的内容是否会和客户端被关闭后发过来的空字符串粘在一起?
2.2 测试过程
- 建立socket后debug锁死在第一个client_connect.recv(500)上,不进行对socket缓冲过来的内容进行读取。
- 紧接着跑到客户端间隔几秒发送2个包过来(一个包大小454)然后关闭客户端,
- ok,此时服务端的socket类的缓冲区已经收到了454+454+客户端关闭的空包
- 回到服务端我们发现第一个recv收到了500个字节大小数据,说明第一个包和第二个包粘在一起了
- 第二个recv发现是第二个包剩下的部分500+408=454+454,由此证明第一个包和第二个包粘包
- temp_data3 = b'' 我们惊喜的发现普通数据包和客户端关闭包不粘包
while True:
temp_data = client_connect.recv(500)
temp_data2 = client_connect.recv(500)
temp_data3 = client_connect.recv(500)
2.3 结论
普通数据包和客户端关闭包不粘包