面试题答案
一键面试检测与应对端口扫描
- 记录连接频率:
- 在代码中,可以维护一个连接记录的字典,记录每个IP地址的连接时间戳。例如,在Python使用
collections.defaultdict
:
from collections import defaultdict connection_timestamps = defaultdict(list) def handle_connection(client_address): current_time = time.time() connection_timestamps[client_address].append(current_time) if len(connection_timestamps[client_address]) > threshold and current_time - connection_timestamps[client_address][0] < time_window: # 判定为端口扫描,进行处理,如封禁IP block_ip(client_address)
- 在代码中,可以维护一个连接记录的字典,记录每个IP地址的连接时间戳。例如,在Python使用
- 设置连接速率限制:
- 使用令牌桶算法来限制连接速率。在C++中可以这样实现:
class TokenBucket { public: TokenBucket(int rate, int capacity) : rate(rate), capacity(capacity), tokens(capacity), last_update(std::chrono::high_resolution_clock::now()) {} bool try_consume(int tokens_to_consume) { refill(); if (tokens >= tokens_to_consume) { tokens -= tokens_to_consume; return true; } return false; } private: void refill() { auto now = std::chrono::high_resolution_clock::now(); std::chrono::duration<double> elapsed = now - last_update; int new_tokens = static_cast<int>(elapsed.count() * rate); tokens = std::min(tokens + new_tokens, capacity); last_update = now; } int rate; int capacity; int tokens; std::chrono::high_resolution_clock::time_point last_update; }; TokenBucket bucket(10, 100); // 每秒生成10个令牌,桶容量100 if (!bucket.try_consume(1)) { // 连接速率过快,拒绝连接 close_connection(); }
检测与应对DDoS攻击
- 流量分析:
- 统计单位时间内的流量。在Java中,可以这样实现:
long startTime = System.currentTimeMillis(); long totalBytes = 0; // 在接收数据的方法中累加流量 public void receiveData(byte[] data) { totalBytes += data.length; long currentTime = System.currentTimeMillis(); if (currentTime - startTime >= timeInterval) { double trafficRate = totalBytes / (currentTime - startTime) * 1000; // 转换为每秒流量 if (trafficRate > threshold) { // 判定为DDoS攻击,采取措施,如封禁IP blockIp(); } startTime = currentTime; totalBytes = 0; } }
- IP信誉系统:
- 可以使用第三方IP信誉库,如MaxMind GeoIP等。在Node.js中可以结合
maxmind
库:
const maxmind = require('maxmind'); async function checkIPReputation(ip) { const cityResponse = await maxmind.open('GeoLite2-City.mmdb'); const city = cityResponse.get(ip); // 假设信誉库返回结果中有恶意标记字段 if (city && city.is_malicious) { // 封禁IP blockIP(ip); } }
- 可以使用第三方IP信誉库,如MaxMind GeoIP等。在Node.js中可以结合
重连机制设计
- 固定时间间隔重连:
- 在C#中,可以使用
System.Timers.Timer
实现固定时间间隔重连:
private System.Timers.Timer reconnectTimer; private void StartReconnectTimer() { reconnectTimer = new System.Timers.Timer(5000); // 5秒重连一次 reconnectTimer.Elapsed += (sender, e) => { TryReconnect(); }; reconnectTimer.AutoReset = true; reconnectTimer.Enabled = true; } private void TryReconnect() { try { // 尝试重新连接Socket socket.Connect(serverEndPoint); reconnectTimer.Stop(); } catch (Exception ex) { // 重连失败,可记录日志 Console.WriteLine($"Reconnect failed: {ex.Message}"); } }
- 在C#中,可以使用
- 指数退避重连:
- 在Python中实现指数退避重连:
import socket import time base_delay = 1 max_delay = 30 delay = base_delay while True: try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((server_ip, server_port)) # 连接成功,重置延迟 delay = base_delay break except socket.error as e: print(f"Connection failed: {e}. Retrying in {delay} seconds...") time.sleep(delay) delay = min(delay * 2, max_delay)
通过以上方法,可以从代码层面检测并应对端口扫描、DDoS等攻击,同时设计健壮的重连机制确保服务的高可用性。