c - 如何 memcpy() struct sockaddr_in

标签 c c89

我正在编写一个服务器客户端程序。 在服务器上,我通过以下数据结构的数组管理客户端:

struct Client
{
    struct sockaddr_in addr;
    /*...*/
}; 

struct Client CLIENTS[MAX_CLI];

当我通过 UDP 套接字从客户端收到第一个数据包时

struct sockaddr_in addr_cli;

memset(&addr_cli,0,sizeof(struct sockaddr_in));
b=recvfrom(SOCK_UDP_FATHER, &pdu, sizeof(pdu), MSG_DONTWAIT,
    (struct sockaddr *)&addr_cli, (socklen_t *)&laddr_cli);

我想将他的地址复制到我的结构中。所以我这样做:

memcpy(&CLIENTS[client].addr,(struct sockaddr*)&addr_cli,
    sizeof(struct sockaddr_in));

printf("IP client: %s",inet_ntoa(CLIENTS[client].addr.sin_addr);

奇怪的是,第一次尝试通信失败,打印0.0.0.0。但客户的下一次尝试是成功的,一切都很顺利。为什么会发生这种情况?

最佳答案

调用 recvfrom 未填充 addr_clirecvfrom 的最后两个参数有点棘手。他们是

struct sockaddr *src_addr,
socklen_t *addrlen

如果src_addr不为NULL,则recvfrom期望addrlen指向src_addr缓冲区的长度。 (通常是sockaddr结构的大小)。如果addrlen的值太小,返回的地址将被截断。调用 recvfrom 后,addrlen 将被设置为实际地址长度。看documentation了解详情。

所以你需要在调用recvfrom()之前初始化laddr_cli:

struct sockaddr_in addr_cli;
socklen_t laddr_cli = sizeof(addr_cli); // <--

memset(&addr_cli,0,laddr_cli);    
b=recvfrom(SOCK_UDP_FATHER, &pdu, sizeof(pdu), MSG_DONTWAIT,
    (struct sockaddr *)&addr_cli, &laddr_cli);

关于c - 如何 memcpy() struct sockaddr_in,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29398634/

相关文章:

c++ - SSL_CTX_load_verify_locations 和可信证书

c - 探索 getchar() 函数

c - 错误: 'for' loop initial declarations are only allowed in c99 mode

c - GLFW GLSL OPENGL问题

c - ANSI C S-Linked List - deleteLast() 无法正常工作

c - 如何使这个后台运行的代码只用一个 kill 命令终止?

c - 在函数之间传递多维数组

c - 在不使用数组的情况下在 C 中查找 100 阶乘中的数字总和

c++ - 将整数转换为字符数组函数

c - 文件不会在 MS Visual Studio 中编译,但会在 GCC 中编译。为什么?