繁体   English   中英

使用 readv 从套接字读取数据

[英]Reading data from socket with readv

我在使用 writev()/readv() 进行客户端-服务器通信时遇到问题。

我有两个这样定义的结构、 headerdata

typedef struct {
    int op;
    int key;
} message_hdr_t;
typedef struct {
    int len;
    char *data;
} message_data_t;

服务器执行(简而言之):

message_hdr_t h = {1, 11};
message_data_t d;
d.len = 3;
strcpy(d.data, "msg");

struct iovec tosend[2];
tosend[0].iov_base = &h;
tosend[0].iov_len = sizeof(message_hdr_t);
tosend[1].iov_base = &d;
tosend[1].iov_len = sizeof(message_data_t);

writev(socket, tosend, 2);
close(socket);

客户(简称):

struct iovec received[2];
readv(socket, received, 2);
message_hdr_t header;
header.op = ((message_hdr_t *) received[0].iov_base)->op;
header.key = ((message_hdr_t *) received[0].iov_base)->key;
printf("Received op: %i, key: %i\n",header.op,header.key;
close(socket);

但是客户端收到段错误,因为received[0].iov_baseNULL 为什么? 套接字正确打开,客户端正确连接到服务器。 这是一个 AF_UNIX 套接字。

首先,在您的服务器代码中,您正在编写一个指针 这没有任何意义。 您不想通过线路传输指针。 要传输字符串,您必须执行以下操作:

char* message = ...;
message_hdr_t h = {1, 11};

uint32_t message_length = strlen(message);

struct iovec tosend[3];

tosend[0].iov_base = &h;
tosend[0].iov_len = sizeof(message_hdr_t);

tosend[1].iov_base = &message_length;
tosend[1].iov_len = sizeof(message_length);

tosend[2].iov_base = message;
tosend[2].iov_len = message_length;

(您可能希望将字符串长度移动到消息头并保存向量的一个元素,并使协议更具可读性)。

其次, readv不会为您分配内存,也不会算出您要读取的字节数。 这是你的工作,以正确初始化iov_baseiov_len在IO载体传递给readv 为了读取动态分配的可变大小字符串,您可能需要读取两次。 首先,读取包含字符串长度的消息的一部分,然后分配字符串,并读取消息的其余部分。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM