【问题标题】:Problem with send, recv and NULL pointer in CC中的send、recv和NULL指针的问题
【发布时间】:2021-09-10 21:09:02
【问题描述】:

我的代码有一个我完全不理解的问题。这是来自服务器的代码:

usr = uslist_return(&users,i);
if(usr != NULL)
{
            send(client,usr,sizeof(usr),0);
            //Some extra code
}
else
{
            utmp.userid = -1;
            send(client,&utmp,sizeof(utmp),0);
}

这是来自客户端的代码:

recv(sock,tmp,sizeof(tmp),0);
if(tmp->userid > 0)
{
       //Some Code
}
else
{
       //Some other code
}

这里的问题是,虽然我检查了 send() 没有发送 NULL 指针,但 send() 发送的指针最终是 NULL。也许它来自recv()。我一点头绪都没有。

忽略 uslist_return(...)。它只是一个返回指针的函数。并且 utmp 与 usr 是同一类型(但不是指针)。

编辑:服务器在 if 括号中发送一个指针,在 else 括号中发送一个结构。当服务器发送指针 usr 并且客户端获取它并将其保存在指针 tmp(相同类型的指针)中时,就会出现问题。由于这个原因,我还没有检查 else 案例。

编辑 2:感谢 Martin James 对此发表评论。 recv() 似乎返回-1。 Perror 显示错误是 Bad Address。我不知道这是什么。

【问题讨论】:

  • send() 发送的指针 I 最终为 NULL - 这是什么意思?你怎么会知道这事?无论如何,sizeof(usr) 是指针的大小,而不是指向的数据。
  • 您想调试客户端或服务器。 netcat aka nc 或 socket 是有用的实用程序。在第一种情况下,usr != NULL,这听起来像是一个用户列表,但你执行 sizeof(usr) ,这是变量的大小而不是用户数。在 usr == NULL 中,您没有告诉我们 utmp 是什么。请提供minimal reproducible example
  • 如果 usr 是指针 sizeof(usr) 是指针的大小(可能是 4 或 8),而不是它所指向的大小。
  • send(), recv() 返回值,千万不要忽略它们:(
  • "Perror 显示错误是 Bad Address。我不知道这是什么。" 可能是因为tmp 的值不是有效地址。我无法确定,因为您的代码不完整。但是,您发布的代码似乎不正确。您可以通过创建 minimal reproducible example 来改进您的问题。

标签: c pointers client-server


【解决方案1】:

您似乎将 count 个用户(例如 27 个)与变量 usrsize 字节(例如 8 个字节)混淆了。 send() 参数 len 是您发送的字节数。如果每条记录的大小都是统一的,那么就是count * sizeof(record),否则需要对每条记录的大小求和。

此外,正如您所提到的,发送指针通常没有意义,因为服务器和客户端使用不同的地址空间。

检查send()recv()的返回值。

【讨论】:

  • 我不太明白。因为,在代码的其他地方,我使用了指针并且没有任何反应。不过,您似乎是对的,因为我还没有达到代码中的那些点。首先我必须这样做。我会检查的。
  • 我可以使用 send(sock,&(*usr),sizeof(*usr),0) 吗?不知道是不是和以前一样。
  • 你还没有告诉我们 usr 是什么类型,所以很难帮助你。如果它是一个 int 并且您只有其中一个,是的,那么 send(..., &usr, sizeof(usr), ..) 是发送存储在 usr 中的值的方式。您没有发送指针。如果 usr 是一个结构,那么您可能需要对其进行序列化(转换值,并确保将指针转换为对客户端有意义的东西)。
  • 确实问题在于发送指针。 usr 是一个结构。我必须分别传递每个成员(int、char 等,而不是复杂类型)。但是,当我错误地发送了一个结构(不是指针)时,客户端只收到了一些字节,除了服务器等待客户端接收剩余字节之外,没有发生错误。
  • 请注意,有一些库可以帮助您进行(反)序列化(也称为编组)。传统上,您会使用 ASN.1,现在您可能会使用 JSON,或者您可以使用 Cap'n Proto 或 Protobuf 等专用库。
猜你喜欢
  • 2014-06-29
  • 1970-01-01
  • 2012-03-11
  • 2021-05-24
  • 2014-05-05
  • 2016-08-02
  • 2022-01-15
  • 2021-03-04
  • 1970-01-01
相关资源
最近更新 更多