服务端代码:bool tpsocket_event_filelog_to_hub(struct tpsocket_handler *handler, struct list_head *buf, int event)
{
//debug_show_tpbuf_list(buf, "TEST", 3);
struct tpsocket_fd *sock = container_of(handler, struct tpsocket_fd, handler);
FileLogSession *session = handler->priv;
if (event != TPSOCKET_EVENT_STREAM) {
DBG_ERR("sock=%p, event=%s\n", sock, tpsocket_event_name(event));
}
switch(event) {
case TPSOCKET_EVENT_LISTEN:
DBG_ERR("TPSOCKET_EVENT_LISTEN: %s:%s Listen\n", sock->addr, sock->port);
break;
case TPSOCKET_EVENT_SHUTDOWN:
DBG_ERR("TPSOCKET_EVENT_LISTEN: %s:%s Shutdown\n", sock->addr, sock->port);
break;
case TPSOCKET_EVENT_ACCEPT:
DBG_ERR("TPSOCKET_EVENT_LISTEN: %s:%s Accepted\n", sock->addr, sock->port);
break;
case TPSOCKET_EVENT_CONNECTED:
DBG_ERR("TPSOCKET_EVENT_LISTEN: %s:%s connected\n", sock->addr, sock->port);
break;
case TPSOCKET_EVENT_REQ_HEAD:
DBG_ERR("TPSOCKET_EVENT_LISTEN: %s Requested path: %s\n", sock->path, sock->parser.http.url);
break;
case TPSOCKET_EVENT_RSP_HEAD:
break;
case TPSOCKET_EVENT_SUB_HEAD:
DBG_ERR("TPSOCKET_EVENT_LISTEN: %s:%s connected\n", sock->addr, sock->port);
break;
case TPSOCKET_EVENT_UPGRADE:
break;
case TPSOCKET_EVENT_STREAM:
if (!session || !session->fp) {
DBG_ERR("Invalid session during write\n");
return false; // 导致连接异常关闭
}
case TPSOCKET_EVENT_MESSAGE:
if (!session || !session->fp) {
DBG_ERR("Invalid session during write\n");
return false;
}
struct tpsocket_buf *chunk;
bool error = false;
list_for_each_entry(chunk, buf, list) {
size_t to_write = chunk->len;
if (session->remaining <= 0)
{
DBG_ERR("Early termination: remaining=0\n");
break;
}
if (to_write > session->remaining) {
DBG_ERR("Data overflow: %zu > %zu\n", to_write, session->remaining);
to_write = session->remaining;
}
if (fwrite(chunk->data, 1, to_write, session->fp) < to_write) {
DBG_ERR("File write error: %s\n", strerror(errno));
error = true;
break;
}
session->remaining -= to_write;
DBG_ERR("session->remaining: %d\n", session->remaining);
if (session->remaining <= 0) break;
}
// 传输完成处理
if (session->remaining <= 0 || error) {
fclose(session->fp);
session->fp = NULL;
// fclose(session->fp);
const char *resp = error ? "HTTP/1.1 500 Internal Error\r\nConnection: close\r\n\r\n"
: "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %zu\r\nConnection: keep-alive\r\n\r\n";
struct tpsocket_buf *resp_buf = tpbuf_snprintf(strlen(resp)+1, resp);
if (resp_buf) tpsocket_write(sock, resp_buf);
// tpsocket_close(sock);
// 资源释放
if (error) unlink(session->filepath);
free(session);
handler->priv = NULL;
}
break;
case TPSOCKET_EVENT_RESET:
break;
case TPSOCKET_EVENT_TIMEOUT:
break;
case TPSOCKET_EVENT_CLOSED:
if (session) {
// 异常关闭时清理资源
if (session->fp) fclose(session->fp);
unlink(session->filepath);
free(session);
handler->priv = NULL;
}
break;
case TPSOCKET_EVENT_ERROR:
default:
break;
}
tpsocket_free_buf(buf, tpsocket_event_name(event), 0);
return true;
}
bool tpsocket_event_filelog_from_hub(struct tpsocket_handler *handler, struct list_head *buf, int event) {
struct tpsocket_fd *sock = container_of(handler, struct tpsocket_fd, handler);
ReadLogSession *session = handler->priv;
if (event != TPSOCKET_EVENT_STREAM) {
DBG_ERR("sock=%p, event=%s\n", sock, tpsocket_event_name(event));
}
#define TRANSFER_CHUNK_SIZE 4096
uint8_t chunk_buf[TRANSFER_CHUNK_SIZE];
switch(event) {
case TPSOCKET_EVENT_LISTEN:
DBG_ERR("TPSOCKET_EVENT_LISTEN");
break;
case TPSOCKET_EVENT_SHUTDOWN:
DBG_ERR("TPSOCKET_EVENT_SHUTDOWN");
break;
case TPSOCKET_EVENT_ACCEPT:
DBG_ERR("TPSOCKET_EVENT_ACCEPT");
break;
case TPSOCKET_EVENT_CONNECTED:
break;
case TPSOCKET_EVENT_REQ_HEAD:
DBG_ERR("TPSOCKET_EVENT_REQ_HEAD");
break;
case TPSOCKET_EVENT_RSP_HEAD:
DBG_ERR("TPSOCKET_EVENT_RSP_HEAD");
break;
case TPSOCKET_EVENT_SUB_HEAD:
break;
case TPSOCKET_EVENT_UPGRADE:
break;
case TPSOCKET_EVENT_WRITABLE:
if (session && session->fp && !session->transfer_complete) {
// 继续传输剩余数据
size_t bytes_read = fread(chunk_buf, 1, sizeof(chunk_buf), session->fp);
if (bytes_read > 0) {
// 构建分块头 [长度]\r\n
char chunk_header[32];
int hdr_len = snprintf(chunk_header, sizeof(chunk_header), "%zx\r\n", bytes_read);
struct tpsocket_buf *hdr_buf = tpbuf_snprintf(hdr_len + 1, chunk_header);
tpsocket_write(sock, hdr_buf);
// 发送数据块
struct tpsocket_buf *data_buf = tpbuf_new(bytes_read);
memcpy(data_buf->data, chunk_buf, bytes_read);
tpsocket_write(sock, data_buf);
// 发送块结束符
struct tpsocket_buf *end_buf = tpbuf_snprintf(3, "\r\n");
tpsocket_write(sock, end_buf);
session->sent_bytes += bytes_read;
}
// 检查是否完成
if (session->sent_bytes >= session->file_size) {
session->transfer_complete = true;
DBG_INFO("Transfer completed via WRITABLE events");
}
}
break;
case TPSOCKET_EVENT_STREAM:
case TPSOCKET_EVENT_MESSAGE:
DBG_ERR("TPSOCKET_EVENT_MESSAGE");
if (!session || !session->fp) {
DBG_ERR("Invalid session during transfer\n");
return false;
}
// 1. 发送HTTP头
if (!session->header_sent) {
char header[512];
int header_len = snprintf(header, sizeof(header),
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n"
"Content-Length: %zu\r\n"
"Connection: keep-alive\r\n\r\n",
session->file_size);
if (header_len <= 0) {
DBG_ERR("Header generation failed\n");
return false;
}
struct tpsocket_buf *header_buf = tpbuf_snprintf(header_len + 1, header);
if (!header_buf || !tpsocket_write(sock, header_buf)) {
DBG_ERR("Failed to send header\n");
return false;
}
session->header_sent = true;
DBG_ERR("HTTP header sent\n");
}
DBG_ERR("Start sent body\n");
// // 8. 分块读取并发送(每次8KB)
// while (!feof(session->fp)) {
// size_t bytes_read = fread(chunk_buf, 1, sizeof(chunk_buf), session->fp);
// if (bytes_read > 0) {
// // 构建分块头 [长度]\r\n
// char chunk_header[32];
// int hdr_len = snprintf(chunk_header, sizeof(chunk_header), "%zx\r\n", bytes_read);
// struct tpsocket_buf *hdr_buf = tpbuf_snprintf(hdr_len + 1, chunk_header);
// tpsocket_write(sock, hdr_buf);
// // 发送数据块
// struct tpsocket_buf *data_buf = tpbuf_new(bytes_read);
// memcpy(data_buf->data, chunk_buf, bytes_read);
// tpsocket_write(sock, data_buf);
// // 发送块结束符
// struct tpsocket_buf *end_buf = tpbuf_snprintf(3, "\r\n");
// tpsocket_write(sock, end_buf);
// session->sent_bytes += bytes_read;
// }
// }
// // 9. 发送结束块
// struct tpsocket_buf *final_buf = tpbuf_snprintf(5, "0\r\n\r\n");
// tpsocket_write(sock, final_buf);
// DBG_INFO("File transfer completed: %zu/%zu bytes",
// session->sent_bytes, session->file_size);
break;
case TPSOCKET_EVENT_CLOSED:
// 清理资源
if (session) {
if (session->fp) fclose(session->fp);
free(session);
handler->priv = NULL;
}
break;
case TPSOCKET_EVENT_ERROR:
default:
break;
}
return true;
}客户端代码:import requests
import logging
from urllib.parse import urlencode
import time
# # 禁用HTTPS证书警告
requests.packages.urllib3.disable_warnings()
def get_device_logs(server_ip: str = "192.168.137.93", port: int = 21443,
mac_address: str = "A1:B2:C3:D4:E5:F6", timeout: int = 15):
"""
Optimized device log retrieval client (with retry mechanism and performance monitoring)
:param server_ip: Server IP address
:param port: Server port
:param mac_address: Device MAC address (format: A1:B2:C3:D4:E5:F6)
:param timeout: Request timeout in seconds
:return: Returns log content on success, None on failure
"""
# 1. Configure URL and headers
url = f"https://{server_ip}:{port}/log/file_log_get"
headers = {
"Device-Mac": mac_address.replace(":", "_"), # Convert to server format
"Connection": "keep-alive"
}
# 2. Configure logger (English output)
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
handlers=[logging.StreamHandler()]
)
# 3. Request with retry mechanism
MAX_RETRIES = 1
for attempt in range(MAX_RETRIES):
try:
start_time = time.time()
# Send GET request (disable SSL verification)
response = requests.get(
url,
headers=headers,
verify=False,
timeout=timeout
)
elapsed = time.time() - start_time
logging.info(f"Request completed! Time: {elapsed:.2f}s, Status: {response.status_code}")
# 4. Process response
if response.status_code == 200:
# Check content type
content_type = response.headers.get('Content-Type', '')
if 'text/plain' in content_type:
return response.text
else:
logging.warning(f"Non-text response: {content_type}, Length: {len(response.content)} bytes")
return response.content.decode('utf-8', errors='replace')
# 5. Error handling (English messages)
logging.error(f"Request failed! Status: {response.status_code}")
if response.status_code >= 400:
error_detail = response.text[:200] + ("..." if len(response.text)>200 else "")
logging.error(f"Error details: {error_detail}")
# Specific status code handling
if response.status_code == 404:
logging.error("Possible causes: 1) Invalid URL 2) MAC not registered")
elif response.status_code == 500:
logging.error("Server internal error, check server logs")
# Retry with exponential backoff
if attempt < MAX_RETRIES - 1:
retry_delay = 2 ** attempt
logging.warning(f"Retrying in {retry_delay}s ({attempt+1}/{MAX_RETRIES})...")
time.sleep(retry_delay)
except requests.exceptions.SSLError as e:
logging.error(f"SSL error: {str(e)}")
except requests.exceptions.ConnectionError:
logging.error("Connection failed! Check: 1) Network 2) Server status 3) Firewall")
except requests.exceptions.Timeout:
logging.error(f"Timeout exceeded ({timeout}s)! Suggestions: 1) Check network 2) Increase timeout")
except Exception as e:
logging.error(f"Unknown error: {str(e)}")
return None
def build_debug_url(server_ip: str, port: int, mac: str) -> str:
"""Generate debug URL with MAC parameter"""
params = {"mac": mac.replace(":", "_")}
return f"https://{server_ip}:{port}/debug?{urlencode(params)}"
if __name__ == "__main__":
print("=" * 60)
print("Device Log Retrieval Client")
print("=" * 60)
# Configurable parameters
logs = get_device_logs(
server_ip="192.168.137.93",
port=21443,
mac_address="A1:B2:C3:D4:E5:F6",
timeout=60
)
if logs:
print("\n" + "=" * 20 + " LOG CONTENT START " + "=" * 20)
# Output first 2000 characters
print(logs[:2000] + ("..." if len(logs)>2000 else ""))
print("=" * 20 + " LOG CONTENT END " + "=" * 20)
print(f"\n Log retrieval successful! Total length: {len(logs)} characters")
# Debug suggestion
debug_url = build_debug_url("192.168.137.93", 21443, "A1:B2:C3:D4:E5:F6")
print(f" Debug tip: Visit {debug_url} for server status")
else:
print(" Log retrieval failed! Check error messages above")
print("=" * 60)
现在读取文件还实现不了,帮我解决下。
最新发布