gpt4 book ai didi

c - accept() 调用不初始化 sockaddr 结构

转载 作者:太空宇宙 更新时间:2023-11-04 01:01:22 25 4
gpt4 key购买 nike

我用 C 编写了一个简短的 TCP 服务器示例,它持续监听端口 12701 上的连接,并将对等方的 sockaddr.sa_family 的值输出到标准输出。程序在无限循环中调用 accept(),它应该用连接的详细信息填充 struct sockaddr,包括 sa_family。

但是,对于第一个 TCP 连接,这并没有正确发生; sockaddr.sa_family 始终为零。所有后续连接都提供正确的值 2 - 只有第一个是错误的。为什么会这样?我还没有找到任何类似问题的报告,但我怀疑我没有正确初始化某些东西或误解了 accept() 的参数。

程序如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>

int main(void)
{
struct sockaddr_in saddr =
{
.sin_family = AF_INET,
.sin_addr.s_addr = htonl(INADDR_ANY),
.sin_port = htons(12701),
};

// open socket to accept() tcp connections
int accept_fd = socket(AF_INET, SOCK_STREAM, 0);
bind(accept_fd, (struct sockaddr *) &saddr, sizeof(struct sockaddr_in));
listen(accept_fd, SOMAXCONN);

socklen_t addrlen;
struct sockaddr * addr;
for(;;)
{
addr = (struct sockaddr *) malloc(sizeof(struct sockaddr));
int child_fd = accept(accept_fd, addr, &addrlen);

// why is this always zero the first time?
printf("addr->sa_family = %d\n", addr->sa_family);

close(child_fd);
free(addr);
}

return 0;
}

最佳答案

这假定要设置连接的 AF_INET

您想将适合您将监听套接字绑定(bind)到的结构的地址传递给 accept(),即 struct sockaddr_in

此外,addrlen 需要设置为传递给 accept() 的地址的大小。

  for (;;)
{
struct sockaddr_in * addr = malloc(sizeof *addr);
socklen_t addrlen = sizeof *addr;

if (NULL == addr)
{
perror("malloc() failed");
/* exit(), break, continue, whatever ... */
}

int child_fd = accept(accept_fd, (struct sockaddr *) addr, &addrlen);
if (-1 == child_fd)
{
perror("accept() failed");
free(addr);
addr = NULL;
/* exit(), break, continue, whatever ... */
}

/* Do stuff. */

close(child_fd);
free(addr);
}

关于c - accept() 调用不初始化 sockaddr 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37631747/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com