sendmsg 得到了错误的地址
sendmsg got Bad address
在学习网络编程(TCP)的时候遇到了这个问题:
我尝试使用 sendmsg() 和 recvmsg() 在客户端和服务器之间交换信息,但是 "sendmsg()" 出现错误 "BAD ADDRESS".
Whosebug上的一些答案提到了内存问题,但我仍然很困惑,不知道该怎么办。
这是代码(相关部分)和结果。
如果有人能帮我解决这个问题,我将不胜感激。
void process_conn_server(int s) //s is the socketfd
{
char buffer[30];
ssize_t size = 0;
struct msghdr msg;
struct iovec *v = (struct iovec *)malloc(3 * sizeof(struct iovec));
if (!v)
{
perror("wrong: allocate memory\n");
return;
}
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_iov = v;
msg.msg_iovlen = 30;
msg.msg_flags = 0;
// vs = v;
v[0].iov_base = buffer;
v[1].iov_base = buffer + 10;
v[2].iov_base = buffer + 20;
v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;
for (;;)
{
size = recvmsg(s, &msg, 0);
if (size == 0)
{
return;
}
sprintf(v[0].iov_base, "%d ", size);
sprintf(v[1].iov_base, "bytes alt");
sprintf(v[2].iov_base, "ogether\n");
v[0].iov_len = strlen(v[0].iov_base);
v[1].iov_len = strlen(v[1].iov_base);
v[2].iov_len = strlen(v[2].iov_base);
sendmsg(s, &msg, 0);
}
}
void process_conn_client(int s)
{
char buffer[30];
ssize_t size = 0;
struct msghdr msg;
struct iovec *v = (struct iovec *)malloc(3 * sizeof(struct iovec));
if (!v)
{
perror("wrong: allocate memory\n");
return;
}
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_iov = v;
msg.msg_iovlen = 30;
msg.msg_flags = 0;
// vc = v;
v[0].iov_base = buffer;
v[1].iov_base = buffer + 10;
v[2].iov_base = buffer + 20;
v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;
// int fd;
for (;;)
{
// fd = open("firstfile.txt", O_RDONLY, 0666);
size = read(0, v[0].iov_base, 10);
printf("%d size\n", size);
if (size > 0)
{
//读到数据,发送给服务器
v[0].iov_len = size;
if (sendmsg(s, &msg, 0) < 0)
{
perror("");
return;
}
v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;
size = recvmsg(s, &msg, 0);
for (int i = 0; i < 3; i++)
{
if (v[i].iov_len > 0)
{
write(1, v[i].iov_base, v[i].iov_len);
}
}
}
}
}
结果:
(base)qin@qin-D~/JuniorB/NetworkProgramming/7master●./client 127.0.0.1
你好
6码
地址错误
其他部分应该是正确的。(我没有在这里上传,因为它们有点长)。当我使用下面的 2 个函数时,这就是我得到的(也是我想要的):
void process_conn_client1(int s)
{
char buffer[30];
ssize_t size = 0;
//申请三块结构类型
struct iovec *v = (struct iovec *)malloc(3 * sizeof(struct iovec));
if (!v)
{
printf("Not enough memory\n");
return;
}
vc = v;
//挂接全局变量,便于释放管理
v[0].iov_base = buffer;
v[1].iov_base = buffer + 10;
v[2].iov_base = buffer + 20;
v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;
int i = 0;
for (;;)
{
size = read(0, v[0].iov_base, 10);
if (size > 0)
{
//读到数据,发送给服务器
v[0].iov_len = size;
writev(s, v, 1);
v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;
size = readv(s, v, 3);
for (i = 0; i < 3; i++)
{
if (v[i].iov_len > 0)
{
write(1, v[i].iov_base, v[i].iov_len);
}
}
}
}
}
void process_conn_server1(int s)
{
char buffer[30];
ssize_t size = 0;
//申请三块结构类型
struct iovec *v = (struct iovec *)malloc(3 * sizeof(struct iovec));
if (!v)
{
printf("Not enough memory\n");
return;
}
vs = v;
v[0].iov_base = buffer;
v[1].iov_base = buffer + 10;
v[2].iov_base = buffer + 20;
v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;
for (;;)
{
size = readv(s, v, 3);
if (size == 0)
{
return;
}
sprintf(v[0].iov_base, "%d ", size);
sprintf(v[1].iov_base, "bytes alt");
sprintf(v[2].iov_base, "ogether\n");
v[0].iov_len = strlen(v[0].iov_base);
v[1].iov_len = strlen(v[1].iov_base);
v[2].iov_len = strlen(v[2].iov_base);
writev(s, v, 3);
}
}
结果:
(base)qin@qin-D~/JuniorB/NetworkProgramming/7master●./client 127.0.0.1
你好
一共6个字节
输入此行和服务器 returns 长度
总共 10 个字节
总共 10 个字节
总共 10 个字节
总共 10 个字节
一共6个字节
"sendmsg()" got error "BAD ADDRESS".
对于process_conn_client中的第一种情况,只需替换
msg.msg_iovlen = 30;
来自
msg.msg_iovlen = 3;
因为 v 包含 3 个条目而不是 30 个(可能你放 30 是因为 10 有 3 个缓冲区)
除此之外还在 process_conn_client 因为你只从 stdin doing[=16= 读取最多 10 个字符]
size = read(0, v[0].iov_base, 10);
只有发送缓冲区的第一部分可以初始化,后面的两个在发送时不会初始化
在学习网络编程(TCP)的时候遇到了这个问题:
我尝试使用 sendmsg() 和 recvmsg() 在客户端和服务器之间交换信息,但是 "sendmsg()" 出现错误 "BAD ADDRESS".
Whosebug上的一些答案提到了内存问题,但我仍然很困惑,不知道该怎么办。
这是代码(相关部分)和结果。
如果有人能帮我解决这个问题,我将不胜感激。
void process_conn_server(int s) //s is the socketfd
{
char buffer[30];
ssize_t size = 0;
struct msghdr msg;
struct iovec *v = (struct iovec *)malloc(3 * sizeof(struct iovec));
if (!v)
{
perror("wrong: allocate memory\n");
return;
}
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_iov = v;
msg.msg_iovlen = 30;
msg.msg_flags = 0;
// vs = v;
v[0].iov_base = buffer;
v[1].iov_base = buffer + 10;
v[2].iov_base = buffer + 20;
v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;
for (;;)
{
size = recvmsg(s, &msg, 0);
if (size == 0)
{
return;
}
sprintf(v[0].iov_base, "%d ", size);
sprintf(v[1].iov_base, "bytes alt");
sprintf(v[2].iov_base, "ogether\n");
v[0].iov_len = strlen(v[0].iov_base);
v[1].iov_len = strlen(v[1].iov_base);
v[2].iov_len = strlen(v[2].iov_base);
sendmsg(s, &msg, 0);
}
}
void process_conn_client(int s)
{
char buffer[30];
ssize_t size = 0;
struct msghdr msg;
struct iovec *v = (struct iovec *)malloc(3 * sizeof(struct iovec));
if (!v)
{
perror("wrong: allocate memory\n");
return;
}
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_iov = v;
msg.msg_iovlen = 30;
msg.msg_flags = 0;
// vc = v;
v[0].iov_base = buffer;
v[1].iov_base = buffer + 10;
v[2].iov_base = buffer + 20;
v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;
// int fd;
for (;;)
{
// fd = open("firstfile.txt", O_RDONLY, 0666);
size = read(0, v[0].iov_base, 10);
printf("%d size\n", size);
if (size > 0)
{
//读到数据,发送给服务器
v[0].iov_len = size;
if (sendmsg(s, &msg, 0) < 0)
{
perror("");
return;
}
v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;
size = recvmsg(s, &msg, 0);
for (int i = 0; i < 3; i++)
{
if (v[i].iov_len > 0)
{
write(1, v[i].iov_base, v[i].iov_len);
}
}
}
}
}
结果:
(base)qin@qin-D~/JuniorB/NetworkProgramming/7master●./client 127.0.0.1
你好
6码
地址错误
其他部分应该是正确的。(我没有在这里上传,因为它们有点长)。当我使用下面的 2 个函数时,这就是我得到的(也是我想要的):
void process_conn_client1(int s)
{
char buffer[30];
ssize_t size = 0;
//申请三块结构类型
struct iovec *v = (struct iovec *)malloc(3 * sizeof(struct iovec));
if (!v)
{
printf("Not enough memory\n");
return;
}
vc = v;
//挂接全局变量,便于释放管理
v[0].iov_base = buffer;
v[1].iov_base = buffer + 10;
v[2].iov_base = buffer + 20;
v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;
int i = 0;
for (;;)
{
size = read(0, v[0].iov_base, 10);
if (size > 0)
{
//读到数据,发送给服务器
v[0].iov_len = size;
writev(s, v, 1);
v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;
size = readv(s, v, 3);
for (i = 0; i < 3; i++)
{
if (v[i].iov_len > 0)
{
write(1, v[i].iov_base, v[i].iov_len);
}
}
}
}
}
void process_conn_server1(int s)
{
char buffer[30];
ssize_t size = 0;
//申请三块结构类型
struct iovec *v = (struct iovec *)malloc(3 * sizeof(struct iovec));
if (!v)
{
printf("Not enough memory\n");
return;
}
vs = v;
v[0].iov_base = buffer;
v[1].iov_base = buffer + 10;
v[2].iov_base = buffer + 20;
v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;
for (;;)
{
size = readv(s, v, 3);
if (size == 0)
{
return;
}
sprintf(v[0].iov_base, "%d ", size);
sprintf(v[1].iov_base, "bytes alt");
sprintf(v[2].iov_base, "ogether\n");
v[0].iov_len = strlen(v[0].iov_base);
v[1].iov_len = strlen(v[1].iov_base);
v[2].iov_len = strlen(v[2].iov_base);
writev(s, v, 3);
}
}
结果:
(base)qin@qin-D~/JuniorB/NetworkProgramming/7master●./client 127.0.0.1
你好
一共6个字节
输入此行和服务器 returns 长度
总共 10 个字节
总共 10 个字节
总共 10 个字节
总共 10 个字节
一共6个字节
"sendmsg()" got error "BAD ADDRESS".
对于process_conn_client中的第一种情况,只需替换
msg.msg_iovlen = 30;
来自
msg.msg_iovlen = 3;
因为 v 包含 3 个条目而不是 30 个(可能你放 30 是因为 10 有 3 个缓冲区)
除此之外还在 process_conn_client 因为你只从 stdin doing[=16= 读取最多 10 个字符]
size = read(0, v[0].iov_base, 10);
只有发送缓冲区的第一部分可以初始化,后面的两个在发送时不会初始化