首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >网络应用程序在Mac OS X上工作,在Linux上无法连接

网络应用程序在Mac OS X上工作,在Linux上无法连接
EN

Stack Overflow用户
提问于 2014-09-12 04:34:27
回答 2查看 586关注 0票数 0

我在我的Mac上写了一个网络应用程序,它应该在Linux上运行,因为我想“嘿,POSIX是POSIX,它应该可以工作”,但现在我在连接到服务器时遇到错误。

代码语言:javascript
复制
TCP_sock = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
if (TCP_sock < 0) {
  syserr("socket");
}
TCP_open = 1;

memset(&addr_hints, 0, sizeof(struct addrinfo));
addr_hints.ai_flags = 0;
addr_hints.ai_family = AF_UNSPEC;
addr_hints.ai_socktype = SOCK_STREAM;
addr_hints.ai_protocol = IPPROTO_TCP;
addr_hints.ai_addrlen = 0;
addr_hints.ai_addr = NULL;
addr_hints.ai_canonname = NULL;
addr_hints.ai_next = NULL;

rc = getaddrinfo(SERVER, PORT, &addr_hints, &addr_result);
if (rc != 0) {
  cleanup();
  fprintf(stderr, "rc=%d\n", rc);
  syserr("getaddrinfo: %s\n", gai_strerror(rc));
  continue;
}

if ((rc = connect(TCP_sock, addr_result->ai_addr, addr_result->ai_addrlen)) != 0) {
  syserr("connect: %s\n", gai_strerror(rc));
  cleanup();
  continue;
}

我得到了一个错误:

代码语言:javascript
复制
ERROR: connect: Bad value for ai_flags
(22; Invalid argument)

我只想说清楚:

代码语言:javascript
复制
SERVER = "localhost"
PORT = "1234"

当然,该端口上有一个运行在localhost上的服务器。会出什么问题呢?

EN

回答 2

Stack Overflow用户

发布于 2014-09-12 05:57:15

根据this Wikipedia article on getaddrinfo的说法,不同系统的实现是不同的。还有,OS X is not fully POSIX compliable (第一段)。它被认证为与SUSv3兼容,但这并不意味着它完全兼容POSIX,并且它不一定实现与其他POSIX-y系统相同的通用功能。

所以当'POSIX是POSIX‘时,OS不是POSIX。您需要仔细研究要调用的方法的实现细节,并找出它们之间的区别。

票数 0
EN

Stack Overflow用户

发布于 2015-10-19 22:32:00

这里有几个问题。

  1. gai_strerror仅将getaddrinfo返回的错误码转换为字符串,而您正在尝试转换connect返回的错误码。失败时,connect应返回-1,您可以检查errno并使用strerror将其转换为字符串。
  2. 就像另一条评论所说的,你正在创建一个IPv6套接字,然后告诉getaddrinfo你可以使用IPv4或IPV6地址。将AF_UNSPEC更改为AF_INET6应该会有所帮助。因此,应该工作得更好的代码如下(考虑到#1和#2)

TCP_sock = socket(PF_INET6,SOCK_STREAM,IPPROTO_TCP);if (TCP_sock < 0) { syserr("socket");} TCP_open = 1;memset(&addr_hints,0,sizeof(struct addrinfo));addr_hints.ai_flags = 0;addr_hints.ai_family = AF_INET6;addr_hints.ai_socktype = SOCK_STREAM;addr_hints.ai_protocol = IPPROTO_TCP;addr_hints.ai_addrlen = 0;addr_hints.ai_addr = NULL;addr_hints.ai_canonname = NULL;addr_hints.ai_next = NULL;rc =getaddrinfo(服务器,端口,&addr_hints,&addr_result);if (rc != 0) { cleanup();fprintf(stderr,"rc=%d\n",rc);syserr("getaddrinfo:%s\n",gai_strerror(rc));继续;} if ((rc = connect(TCP_sock,addr_result->ai_addr,addr_result->ai_addrlen)) != 0) { syserr(" connect:%s\n",strerror(errno));cleanup();continue;}

  • 使用getaddrinfo的通常方法是先调用它,然后使用addrinfo结构中的信息创建套接字并连接它。Linux手册页上有一个很好的示例,其中包含相关摘录。

成员集( &hints,0,sizeof(struct addrinfo));hints.ai_family = AF_UNSPEC;/* Allow IPv4 or IPv6 */ hints.ai_socktype = SOCK_DGRAM;/*数据报套接字*/ hints.ai_flags = AI_PASSIVE;通配符IP地址的/* */ hints.ai_protocol = 0;/*任意协议*/ hints.ai_canonname = NULL;hints.ai_addr = NULL;hints.ai_next = NULL;s= getaddrinfo(NULL,argv1,&hints,&result);if (s != 0) { fprintf(stderr,"getaddrinfo:%s\n",gai_strerror(s));exit(EXIT_FAILURE);} /* getaddrinfo()返回地址结构列表。尝试每个地址,直到我们成功绑定(2)。如果socket(2) (或bind(2))失败,我们(关闭套接字并)尝试下一个地址。*/ for (rp =结果;rp != NULL;rp = rp->ai_next) { sfd =套接字(rp->ai_family,rp->ai_socktype,rp->ai_ == );if (sfd == -1)继续;if (bind(sfd,rp->ai_addr,rp->ai_addrlen) == 0) break;/*成功*/ close(sfd);} if (rp == NULL) { /*无地址成功*/ fprintf(stderr,“无法绑定\n”);退出(EXIT_FAILURE);}freeaddrinfo(==);不再需要/* */

这里的主要内容是使用addrinfo结构中的ai_family、ai_socktype和ai_protocol来创建适合与结构中的sockaddr一起使用的套接字。

  • 至于为什么它可以在Mac而不是Linux上工作,我不确定,但我的直觉是它与V4映射的IPv6套接字功能有关,这些功能允许内核使用您的IPv6套接字与IPv4主机通信。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25796459

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档