Bri*_* SP 5 c sockets udp getaddrinfo
所以,在我收到这个错误后,我一直在这里寻找答案,几乎每个人都有一个困难的方法来修复这个错误,但没有人解释为什么会出现这个错误,所以我不认为这个问题是完全重复。
我用 C 语言编写了一个 TCP 套接字,并使用“getaddrinfo”函数使套接字与主机名一起工作,效果非常好!你可以在github上找到我的代码。
但是当我尝试通过“getaddrinfo”创建UDP 套接字时,出现此错误:
ai_socktype 不支持 Servname
客户端.c
const char *host = argv[1];
const char *service = argv[2];
const char *string = argv[3];
struct addrinfo addrCriteria;
memset(&addrCriteria, 0, sizeof(addrCriteria));
addrCriteria.ai_family = AF_UNSPEC;
addrCriteria.ai_socktype = SOCK_DGRAM;
addrCriteria.ai_protocol = IPPROTO_UDP;
struct addrinfo *servAddr;
int ret = getaddrinfo(host, service, &addrCriteria, &servAddr);
if(ret != 0)
sysError(gai_strerror(ret));
Run Code Online (Sandbox Code Playgroud)
我意识到,当我给“service”提供像 8080 这样的数字输入时,不会返回任何错误,但是当我使用指向端口/8081 的字符串作为服务名称(例如“tproxy”)时,“gai_strerror”会返回提到的错误。
显然,gai_strerror 说:“‘SOCK_DGRAM’套接字类型不支持服务名称”,但为什么呢?我的意思是“getaddrinfo”不支持 UDP 套接字上的名称服务的确切原因?
有没有其他方法可以使用 UDP 套接字的服务名称而不是端口号?如何?
TL;DR:没有tproxyUDP 端口。
tproxy如果您在服务数据库中查找UDP 套接字的服务,
getent services tproxy/udp
Run Code Online (Sandbox Code Playgroud)
您不会得到任何输出,因为tproxy它不是 UDP 服务。如果您查看所有tproxy服务(无论协议如何)getent services | grep -e tproxy,您会看到
tproxy 8081/tcp
Run Code Online (Sandbox Code Playgroud)
这意味着tproxy服务仅针对 TCP 协议定义。
这意味着,如果您getaddrinfo()为 service 请求 UDP 套接字8081,您将找不到任何内容,因为tproxy仅针对 TCP 而不是 UDP 定义。
与您请求 UDP 套接字提供xmpp-client服务的情况进行比较。至少我的服务数据库(getent services xmpp-client/udp)响应
xmpp-client 5222/udp jabber-client
Run Code Online (Sandbox Code Playgroud)
事实上,getaddrinfo()很高兴提供此类 UDP 套接字的套接字描述(使用xmpp-client或jabber-client作为服务)。
因此,类似的服务xmpp-client确实定义了 TCP 和 UDP 端口。在我的系统上,getent services | grep -e xmpp-client显示
xmpp-client 5222/tcp jabber-client
xmpp-client 5222/udp jabber-client
Run Code Online (Sandbox Code Playgroud)
由于 TCP 和 UDP 是 IP 上的不同协议,因此服务可以使用不同的端口号进行 TCP 和 UDP 通信是有道理的。因此,假设服务数据库应该为 TCP 和 UDP 套接字返回相同的端口号是不合理的。
换句话说,您遇到错误是因为您错误地认为由于某些服务使用 TCP 端口,并且在服务数据库中注册了名称,因此您也应该能够使用该名称来指定 UDP 端口号。
TCP 和 UDP 是独立的协议,它们的端口号空间也是独立的。例如,TCP 端口 512 由 Unix r-service 使用exec,而 UDP 端口 512 由邮件通知服务使用biff。