URL Parsing

url解析

rawURL := "postgres://user:pass@host.com:5432/path?k=v#f"
u, err := url.Parse(rawURL)
if err != nil {
	panic(err)
}
fmt.Println("scheme:", u.Scheme)
fmt.Println("opaque:", u.Opaque)
fmt.Println("user:", u.User)
fmt.Println("user.username:", u.User.Username())
p, _ := u.User.Password()
fmt.Println("user.password:", p)
fmt.Println("host:", u.Host)
host, port, _ := net.SplitHostPort(u.Host)
fmt.Println("host.splitHost:", host)
fmt.Println("host.splitPort:", port)
fmt.Println("path:", u.Path)
fmt.Println("rawPath:", u.RawPath)
fmt.Println("forceQuery:", u.ForceQuery)
fmt.Println("rawQuery:", u.RawQuery)
m, _ := url.ParseQuery(u.RawQuery)
fmt.Println("rawQuery map:", m)
fmt.Println("fragment:", u.Fragment)
fmt.Println("rawFragment:", u.RawFragment)

scheme: postgres
opaque:
user: user:pass
user.username: user
user.password: pass
host: host.com:5432
host.splitHost: host.com
host.splitPort: 5432
path: /path
rawPath:
forceQuery: false
rawQuery: k=v
rawQuery map: map[k:[v]]
fragment: f
rawFragment:

# -*- coding: utf-8 -*- import socket import ssl # 导入SSL模块 import time import os import logging from urllib.parse import urlparse def send_file(url: str, mac_address: str, file_path: str, chunk_size: int = 4096): # Parse URL try: parsed_url = urlparse(url) host = parsed_url.hostname port = parsed_url.port or 443 # 默认端口改为443 path = parsed_url.path if not host: raise ValueError("Missing host in URL") except Exception as e: logging.error(f"URL parsing failed: {e}") return False # Configure logging logging.basicConfig( level=logging.INFO, format='%(asctime)s [%(levelname)s] %(message)s', handlers=[logging.FileHandler('transfer.log'), logging.StreamHandler()] ) # 1. Read file content try: file_size = os.path.getsize(file_path) logging.info(f"Preparing to send to {path}: {file_path} ({file_size} bytes)") except Exception as e: logging.error(f"File load failed: {e}") return False # 2. Create SSL socket connection with retry MAX_RETRIES = 3 RETRY_DELAY = 2 # seconds for attempt in range(MAX_RETRIES): try: # 创建SSL上下文 context = ssl.create_default_context() context.check_hostname = True # 验证主机名 # 创建原始socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(30) # 包装为SSL socket ssl_sock = context.wrap_socket(sock, server_hostname=host) ssl_sock.connect((host, port)) logging.info(f"SSL connection established to {host}:{port}") break except Exception as e: if attempt < MAX_RETRIES - 1: logging.warning(f"SSL connection failed ({attempt+1}/{MAX_RETRIES}): {e}, retrying in {RETRY_DELAY}s...") time.sleep(RETRY_DELAY) else: logging.error(f"Max SSL connection retries reached: {e}") return False # 3. Send custom header with URL path try: header = ( f"Path:{path}\n" f"MAC:{mac_address}\n" f"Size:{file_size}\n\n" # Double newline ends header ).encode('utf-8') ssl_sock.sendall(header) # 使用SSL socket发送 # Wait for server ACK ack = ssl_sock.recv(3) # 使用SSL socket接收 if ack != b'ACK': raise ConnectionError(f"Protocol verification failed, received: {ack}") logging.info(f"Header sent successfully: Path={path}, MAC={mac_address}") except Exception as e: logging.error(f"Header send error: {e}") ssl_sock.close() return False # 4. Send file in chunks bytes_sent = 0 start_time = time.time() last_heartbeat = time.time() try: with open(file_path, 'rb') as f: while bytes_sent < file_size: # Heartbeat every 15 seconds if time.time() - last_heartbeat > 15: ssl_sock.sendall(b'\x01') # 使用SSL socket发送心跳 ack = ssl_sock.recv(1) # 使用SSL socket接收ACK if ack != b'\x06': raise ConnectionError(f"Heartbeat no response, received: {ack}") last_heartbeat = time.time() # Read and send data chunk chunk = f.read(chunk_size) if not chunk: break ssl_sock.sendall(chunk) # 使用SSL socket发送数据 bytes_sent += len(chunk) # Smart progress update current_progress = bytes_sent / file_size * 100 elapsed_time = time.time() - start_time # 优化进度显示逻辑 if current_progress.is_integer() or elapsed_time > 1: logging.info(f"Sending: {bytes_sent}/{file_size} bytes ({current_progress:.1f}%)") # Send end marker ssl_sock.sendall(b'EOF') end_ack = ssl_sock.recv(3) if end_ack != b'END': raise ConnectionError(f"End confirmation failed, received: {end_ack}") except Exception as e: logging.error(f"Transfer interrupted: {e}") save_resume_point(bytes_sent) return False # 5. Close connection finally: ssl_sock.close() # 关闭SSL socket elapsed = time.time() - start_time if bytes_sent == file_size: speed = file_size / (elapsed * 1024) # KB/s logging.info(f"Transfer successful! Time: {elapsed:.2f}s, Speed: {speed:.2f} KB/s") return True return False def save_resume_point(position): """Save resume position""" try: with open('transfer_resume.dat', 'w') as f: f.write(str(position)) logging.info(f"Resume point saved: {position} bytes") except Exception as e: logging.error(f"Save resume point failed: {e}") def resume_transfer(url, mac, file_path, chunk_size=4096): """Resume transfer function""" try: with open('transfer_resume.dat', 'r') as f: bytes_sent = int(f.read().strip()) logging.info(f"Resume point detected: {bytes_sent} bytes") with open(file_path, 'rb') as src_file: src_file.seek(bytes_sent) return send_file(url, mac, file_path, chunk_size) except: logging.warning("No valid resume point, starting new transfer") return send_file(url, mac, file_path, chunk_size) if __name__ == "__main__": # 修改为HTTPS URL SERVER_URL = "https://192.168.137.64:21443/log/file_log" TEST_MAC = "A1:B2:C3:D4:E5:F6" TEST_FILE = "test_file.log" print("="*50) # 使用恢复功能 resume_transfer(SERVER_URL, TEST_MAC, TEST_FILE) print("="*50) 按照上个问题的要求修改这个代码。
最新发布
10-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值