UNIX域套接字中如何实现数据的分批发送与接收
UNIX域套接字分批传输实现方案
一、字节级分批传输(按固定大小拆分)
服务端修改(Server.c)
通过循环控制每次发送的字节数,跟踪已发送数据量,直到全部数据发送完成:
// assume str is a string with names of animals separated by "\t" size_t total_len = strlen(str); size_t sent = 0; const size_t batch_size = 100; // 每批次发送100字节 while (sent < total_len) { // 计算当前批次实际要发送的长度(避免最后一批不足100字节) size_t send_len = (total_len - sent) > batch_size ? batch_size : (total_len - sent); ssize_t ret = write(msgSocket, str + sent, send_len); if (ret == -1) { perror("error while sending data to client"); break; } sent += ret; // 可选:添加延迟模拟分批传输,如 usleep(1000); }
客户端修改(Client.c)
客户端需要循环接收,直到收完所有数据。建议先接收总长度,再按批次接收,保证数据完整性:
// 先接收数据总长度 size_t total_len = 0; ssize_t ret = read(msgSocket, &total_len, sizeof(total_len)); if (ret == -1) { perror("error while receiving total length"); return; } char buffer[BUFFER_SIZE]; size_t received = 0; memset(buffer, 0, BUFFER_SIZE); while (received < total_len) { size_t recv_len = (total_len - received) > BUFFER_SIZE ? BUFFER_SIZE : (total_len - received); ret = read(msgSocket, buffer + received, recv_len); if (ret == -1) { perror("error while receiving data"); break; } received += ret; } // 处理完整接收的数据
注意:服务端需要先发送
total_len,再分批发送数据;如果不想传递总长度,也可以约定结束标记,但传递总长度的方式更可靠。
二、按动物名称分批(每次10个)
服务端修改(Server.c)
先按制表符分割字符串得到单个动物名称,每攒够10个就拼接成批次发送:
// assume str is a string with names of animals separated by "\t" // 先复制原字符串避免被strtok修改 char *str_copy = strdup(str); char *token = strtok(str_copy, "\t"); int count = 0; char batch[1024]; // 假设单批次拼接后不超过此大小 memset(batch, 0, sizeof(batch)); while (token != NULL) { // 拼接当前动物名到批次 if (count > 0) { strcat(batch, "\t"); } strcat(batch, token); count++; // 每10个发送一次 if (count == 10) { ssize_t ret = write(msgSocket, batch, strlen(batch)); if (ret == -1) { perror("error while sending batch data"); break; } // 重置批次缓存和计数 memset(batch, 0, sizeof(batch)); count = 0; } token = strtok(NULL, "\t"); } // 发送剩余不足10个的动物名 if (count > 0) { ssize_t ret = write(msgSocket, batch, strlen(batch)); if (ret == -1) { perror("error while sending remaining data"); } } free(str_copy); // 释放复制的字符串
客户端修改(Client.c)
循环接收每个批次,分割后处理单个动物名称,直到服务端关闭连接:
char buffer[BUFFER_SIZE]; ssize_t ret; while (1) { memset(buffer, 0, BUFFER_SIZE); ret = read(msgSocket, buffer, BUFFER_SIZE - 1); // 留一个字节存结束符 if (ret == -1) { perror("error while receiving data"); break; } else if (ret == 0) { // 服务端关闭连接,接收完成 break; } // 分割当前批次的动物名称 char *token = strtok(buffer, "\t"); while (token != NULL) { // 处理单个动物名称,比如打印或存储 printf("Received animal: %s\n", token); token = strtok(NULL, "\t"); } }
内容的提问来源于stack exchange,提问作者Mareek Roy
相关产品推荐
相关产品推荐

