[待验证]strncpy和snprintf的效率

本文深入探讨了优快云博客中的时间结构(timeval与timespec)、字符串复制效率比较以及snprintf与strncpy的使用,提供了一次全面的时间与字符串操作技术之旅。
struct timeval 和 struct timespec
http://blog.youkuaiyun.com/perfectpdl/article/details/6182777

gettimeofday() -- 获取当前时间(保存在结构体timeval中)
http://hi.baidu.com/zengzhaonong/item/9a3fff2f92b82bd50e37f950

snprintf与strncpy效率对比
http://blog.youkuaiyun.com/one132/article/details/5683880

字符串copy效率大比拼~
http://blog.youkuaiyun.com/wavemoon/article/details/4952904

worker.c: In function 'worker_file_log_read_handle': worker.c:3851:9: error: unused variable 'limit' [-Werror=unused-variable] 3851 | int limit = limit_str ? atoi(limit_str) : 100; | ^~~~~ worker.c:3790:11: error: unused variable 'end_time' [-Werror=unused-variable] 3790 | char *end_time = common_find_key_from_buf(buf, "End-Time"); | ^~~~~~~~ worker.c:3789:11: error: unused variable 'start_time' [-Werror=unused-variable] 3789 | char *start_time = common_find_key_from_buf(buf, "Start-Time"); | ^~~~~~~~~~ worker.c:3842:5: error: 'strncpy' output may be truncated copying 255 bytes from a string of length 255 [-Werror=stringop-truncation] 3842 | strncpy(session->filepath, filepath, sizeof(session->filepath)-1); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cc1: all warnings being treated as errors // 日志读取处理函数 bool worker_file_log_read_handle(WORKER_CTX *worker_ctx, struct tpsocket_fd *sock, struct list_head *buf) { // 1. 解析查询参数 char *mac = common_find_key_from_buf(buf, "Device-Mac"); char *offset_str = common_find_key_from_buf(buf, "Offset"); char *limit_str = common_find_key_from_buf(buf, "Limit"); char *start_time = common_find_key_from_buf(buf, "Start-Time"); char *end_time = common_find_key_from_buf(buf, "End-Time"); char *follow = common_find_key_from_buf(buf, "Follow"); // 2. MAC验证格式化 if (!mac || strlen(mac) < 12) { DBG_ERR("Invalid MAC address\n"); const char *resp = "HTTP/1.1 400 Bad Request\r\n\r\n"; struct tpsocket_buf *resp_buf = tpbuf_snprintf(strlen(resp)+1, resp); if (resp_buf) tpsocket_write(sock, resp_buf); return false; } char processed_mac[18] = {0}; strncpy(processed_mac, mac, sizeof(processed_mac)-1); for (char *p = processed_mac; *p; p++) if (*p == ':') *p = '_'; // 3. 构建日志文件路径 char filepath[256]; snprintf(filepath, sizeof(filepath), "%s/%s/log.txt", FILELOG_PATH, processed_mac); // 4. 检查文件是否存在 if (access(filepath, F_OK) != 0) { DBG_ERR("Log file not found: %s\n", filepath); const char *resp = "HTTP/1.1 404 Not Found\r\n\r\n"; struct tpsocket_buf *resp_buf = tpbuf_snprintf(strlen(resp)+1, resp); if (resp_buf) tpsocket_write(sock, resp_buf); return false; } // 5. 打开日志文件 FILE *fp = fopen(filepath, "r"); if (!fp) { DBG_ERR("Failed to open log file: %s\n", strerror(errno)); const char *resp = "HTTP/1.1 500 Internal Error\r\n\r\n"; struct tpsocket_buf *resp_buf = tpbuf_snprintf(strlen(resp)+1, resp); if (resp_buf) tpsocket_write(sock, resp_buf); return false; } // 6. 创建读取会话 LogReadSession *session = calloc(1, sizeof(LogReadSession)); if (!session) { fclose(fp); const char *resp = "HTTP/1.1 507 Insufficient Storage\r\n\r\n"; struct tpsocket_buf *resp_buf = tpbuf_snprintf(strlen(resp)+1, resp); if (resp_buf) tpsocket_write(sock, resp_buf); return false; } session->fp = fp; session->follow_mode = (follow && strcmp(follow, "true") == 0); strncpy(session->mac, mac, sizeof(session->mac)-1); strncpy(session->filepath, filepath, sizeof(session->filepath)-1); // 获取文件状态 struct stat st; fstat(fileno(fp), &st); session->last_modified = st.st_mtime; // 7. 设置初始读取位置 int offset = offset_str ? atoi(offset_str) : 0; int limit = limit_str ? atoi(limit_str) : 100; if (offset > 0) { // 跳过指定行数 char buf[1024]; int lines_skipped = 0; while (fgets(buf, sizeof(buf), fp) && lines_skipped < offset) { lines_skipped++; } } session->current_offset = ftell(fp); session->sent_bytes = 0; // 8. 设置回调私有数据 sock->handler.cb = tpsocket_event_log_read_handler; sock->handler.priv = session; // 9. 发送HTTP响应头 if (session->follow_mode) { // 实时监控模式 - SSE流 const char *header = "HTTP/1.1 200 OK\r\n" "Content-Type: text/event-stream\r\n" "Connection: keep-alive\r\n" "Cache-Control: no-cache\r\n\r\n"; struct tpsocket_buf *header_buf = tpbuf_snprintf(strlen(header)+1, header); if (header_buf) tpsocket_write(sock, header_buf); DBG_ERR("Started live log monitor for %s\n", mac); } else { // 普通查询模式 const char *header = "HTTP/1.1 200 OK\r\n" "Content-Type: text/plain\r\n" "Transfer-Encoding: chunked\r\n\r\n"; struct tpsocket_buf *header_buf = tpbuf_snprintf(strlen(header)+1, header); if (header_buf) tpsocket_write(sock, header_buf); // 立即触发数据推送 struct list_head dummy_buf; INIT_LIST_HEAD(&dummy_buf); tpsocket_event_log_read_handler(&sock->handler, &dummy_buf, TPSOCKET_EVENT_WRITABLE); } return true; }// 日志读取回调处理函数 bool tpsocket_event_log_read_handler(struct tpsocket_handler *handler, struct list_head *buf, int event) { struct tpsocket_fd *sock = container_of(handler, struct tpsocket_fd, handler); LogReadSession *session = handler->priv; if (event != TPSOCKET_EVENT_STREAM) { DBG_ERR("sock=%p, event=%s\n", sock, tpsocket_event_name(event)); } if (!session || !session->fp) { DBG_ERR("Invalid log read session\n"); return false; } 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_WRITABLE: // 可写事件 - 推送日志数据 send_log_data(sock, session); break; case TPSOCKET_EVENT_STREAM: // 非实时模式完成处理 if (!session->follow_mode) { // 发送结束标识 const char *end_chunk = "0\r\n\r\n"; struct tpsocket_buf *end_buf= tpbuf_snprintf(strlen(end_chunk)+1, end_chunk); if (end_buf) tpsocket_write(sock, end_buf); // 关闭连接 tpsocket_close(sock); } break; case TPSOCKET_EVENT_RESET: break; case TPSOCKET_EVENT_TIMEOUT: break; case TPSOCKET_EVENT_CLOSED: // 连接关闭或错误 - 清理资源 DBG_ERR("Log read session closed for %s\n", session->mac); if (session->fp) fclose(session->fp); free(session); handler->priv = NULL; break; case TPSOCKET_EVENT_ERROR: default: break; } tpsocket_free_buf(buf, tpsocket_event_name(event), 0); return true; }
10-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值