【问题标题】:language C, TCP Server and Client语言 C、TCP 服务器和客户端
【发布时间】:2025-03-01 13:20:02
【问题描述】:

我正在尝试创建一个 tcpServer 和 tcpClient 消息终端。我遇到了一些我无法工作的代码问题

我在这里关注本指南https://www.youtube.com/watch?v=BIJGSQEipEE

int newSocket = accept(sockfd, (struct sockaddr*)&newAddr, sizeof(newAddr));
printf("Connection accepted from %s:%d\n", inet_ntoa(newAddr.sin_addr), ntoa(newAddr.sin_port));

我的错误代码是:

tcpServer.c:50:64: warning: incompatible integer to pointer conversion passing 'unsigned long' to parameter of type 'socklen_t *' (aka 'unsigned int *') [-Wint-conversion]
        newSocket = accept(sockfd, (struct sockaddr*)&newAddr, sizeof(newAddr));
                                                               ^~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/sys/socket.h:686:73: note: passing argument to parameter here
int     accept(int, struct sockaddr * __restrict, socklen_t * __restrict)
                                                                        ^
tcpServer.c:54:81: warning: implicit declaration of function 'ntoa' is invalid in C99 [-Wimplicit-function-declaration]
        printf("Connection accepted from %s:%d\n", inet_ntoa(newAddr.sin_addr), ntoa(newAddr.sin_port));

为什么会出现错误2?

谢谢你帮助我:)

【问题讨论】:

  • POSIX accept() 的第三个参数必须是“指向socklen_t 的指针”。您的代码试图传递不兼容的 size_t 类型的值。显然,您链接到的 youtube 指南包含错误信息

标签: c macos tcp server client


【解决方案1】:

accept的原型是这样的:

int accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len);

(来自Open Group Base Specification Issue 7

address_len 参数是指向socklen_t 对象的指针,而不是数字长度。

相反,您应该创建一个 socklen_t 类型的变量,并为其分配您尝试传递的大小:

socklen_t newAddrLength = sizeof(newAddr);

然后,您可以在对accept 的调用中传递指向该变量的指针:

newSocket = accept(sockfd, (struct sockaddr*)&newAddr, &newAddrLength);

我不确定你想用ntoa 做什么。我相信您想要使用的函数是ntohs,它将sin_port 成员的网络顺序转换为主机顺序uint16_t

ntohs(newAddr.sin_port))

然后,您需要将其转换为标准整数类型,或使用<inttypes.h> 中的PRIu16 格式宏:

#include <inttypes.h>
printf("Connection accepted from %s:%" PRIu16 "\n", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));

【讨论】:

  • 谢谢 :)