面试题答案
一键面试优化方面
- 缓冲区管理:
- 增大套接字接收和发送缓冲区大小,以减少数据丢失。在Python中,可以使用
setsockopt
方法设置SO_SNDBUF
(发送缓冲区)和SO_RCVBUF
(接收缓冲区)选项。 - 合理管理应用层缓冲区,例如使用队列来暂存待发送或已接收的数据,防止数据积压。
- 增大套接字接收和发送缓冲区大小,以减少数据丢失。在Python中,可以使用
- 超时处理:
- 设置适当的套接字超时时间,避免长时间等待无响应的连接。在Python中,使用
socket.settimeout
方法设置超时时间。如果在超时时间内没有完成数据接收或发送,抛出timeout
异常,程序可以捕获并进行相应处理。
- 设置适当的套接字超时时间,避免长时间等待无响应的连接。在Python中,使用
- 重传机制:
- 实现应用层的重传机制,当检测到丢包时(例如通过确认机制,若未收到对方的确认信息),重新发送数据。可以为每个发送的数据块编号,并记录发送状态,若超时未收到确认则重发。
- 连接管理:
- 处理连接中断后的自动重连,当检测到连接中断(例如捕获到
ConnectionResetError
等异常),程序应尝试重新连接服务器。可以设置重试次数和重试间隔时间。
- 处理连接中断后的自动重连,当检测到连接中断(例如捕获到
代码框架
以下是一个简单的Python代码框架,展示如何实现上述优化策略:
服务器端代码:
import socket
import time
def server():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 增大缓冲区
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 65536)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 65536)
server_socket.bind(('127.0.0.1', 8888))
server_socket.listen(5)
print('Server is listening...')
while True:
try:
client_socket, client_address = server_socket.accept()
client_socket.settimeout(10) # 设置超时时间
print(f'Connected by {client_address}')
while True:
try:
data = client_socket.recv(1024)
if not data:
break
# 处理接收到的数据
print(f'Received: {data.decode()}')
# 发送确认信息
client_socket.sendall(b'ACK')
except socket.timeout:
print('Receive timeout, waiting for new data...')
except Exception as e:
print(f'Error: {e}')
break
client_socket.close()
except Exception as e:
print(f'Error: {e}')
server_socket.close()
if __name__ == '__main__':
server()
客户端代码:
import socket
import time
def client():
max_retries = 5
retry_delay = 5
for attempt in range(max_retries):
try:
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 65536)
client_socket.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 65536)
client_socket.settimeout(10) # 设置超时时间
client_socket.connect(('127.0.0.1', 8888))
print('Connected to server')
data_to_send = b'Hello, Server!'
while True:
try:
client_socket.sendall(data_to_send)
# 等待确认信息
ack = client_socket.recv(1024)
if ack == b'ACK':
print('Data sent successfully')
else:
print('Received unexpected response, resending...')
except socket.timeout:
print('Send or receive timeout, resending...')
except Exception as e:
print(f'Error: {e}')
break
client_socket.close()
break
except ConnectionRefusedError:
print(f'Connection refused, retry attempt {attempt + 1} in {retry_delay} seconds...')
time.sleep(retry_delay)
else:
print('Max retry attempts reached, unable to connect.')
if __name__ == '__main__':
client()
上述代码框架中,服务器端和客户端都设置了较大的缓冲区,并且设置了套接字超时时间。客户端实现了连接失败后的自动重连机制,同时在数据发送过程中使用了简单的确认和重传机制。