1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
| #define _GNU_SOURCE #include <sys/uio.h> #include <unistd.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h>
/** * 使用pwritev进行聚集写入 */ int demo_pwritev_basic() { int fd; struct iovec iov[3]; ssize_t total_bytes; // 准备要写入的数据 char data1[] = "First part of the message\n"; char data2[] = "Second part with more content "; char data3[] = "and final part.\n"; printf("=== pwritev 基本使用示例 ===\n"); printf("准备写入的数据:\n"); printf("数据1: %s", data1); printf("数据2: %s", data2); printf("数据3: %s", data3); // 创建测试文件 fd = open("test_pwritev.txt", O_CREAT | O_WRONLY | O_TRUNC, 0644); if (fd == -1) { perror("创建测试文件失败"); return -1; } // 设置iovec数组 iov[0].iov_base = data1; iov[0].iov_len = strlen(data1); iov[1].iov_base = data2; iov[1].iov_len = strlen(data2); iov[2].iov_base = data3; iov[2].iov_len = strlen(data3); // 使用pwritev写入数据 total_bytes = pwritev(fd, iov, 3, 0); if (total_bytes == -1) { perror("pwritev 失败"); close(fd); return -1; } printf("\npwritev 写入了 %zd 字节到文件\n", total_bytes); // 读取并验证写入的数据 char buffer[256]; lseek(fd, 0, SEEK_SET); ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1); if (bytes_read > 0) { buffer[bytes_read] = '\0'; printf("\n文件内容验证:\n%s", buffer); } close(fd); unlink("test_pwritev.txt"); return 0; }
/** * 演示pwritev写入HTTP响应头 */ int demo_pwritev_http_response() { int fd; struct iovec iov[4]; ssize_t total_bytes; printf("\n=== pwritev HTTP响应示例 ===\n"); // HTTP响应的各个部分 char status_line[] = "HTTP/1.1 200 OK\r\n"; char headers[] = "Content-Type: text/html\r\n" "Content-Length: 25\r\n" "Connection: close\r\n"; char separator[] = "\r\n"; char body[] = "<html><body>Hello</body></html>"; // 创建测试文件 fd = open("http_response.txt", O_CREAT | O_WRONLY | O_TRUNC, 0644); if (fd == -1) { perror("创建HTTP响应文件失败"); return -1; } // 设置iovec数组 iov[0].iov_base = status_line; iov[0].iov_len = strlen(status_line); iov[1].iov_base = headers; iov[1].iov_len = strlen(headers); iov[2].iov_base = separator; iov[2].iov_len = strlen(separator); iov[3].iov_base = body; iov[3].iov_len = strlen(body); // 一次性写入完整的HTTP响应 total_bytes = pwritev(fd, iov, 4, 0); if (total_bytes == -1) { perror("pwritev 写入HTTP响应失败"); close(fd); return -1; } printf("成功写入HTTP响应,共 %zd 字节\n", total_bytes); // 显示生成的HTTP响应 char buffer[512]; lseek(fd, 0, SEEK_SET); ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1); if (bytes_read > 0) { buffer[bytes_read] = '\0'; printf("\n生成的HTTP响应:\n%s", buffer); } close(fd); unlink("http_response.txt"); return 0; }
int main() { if (demo_pwritev_basic() == 0) { demo_pwritev_http_response(); printf("\n=== pwritev 使用总结 ===\n"); printf("优点:一次系统调用写入多个缓冲区,提高效率\n"); printf("适用场景:网络协议数据发送,日志记录,配置文件更新\n"); } return 0; }
|