首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我正在开发一个服务器,ip作为参数传递不起作用

问我正在开发一个服务器,ip作为参数传递不起作用
EN

Stack Overflow用户
提问于 2020-07-06 18:02:49
回答 1查看 163关注 0票数 0

我在用:

代码语言:javascript
复制
struct in_addr ip;                                         
#define HOST_PORT atoi(argv[2])
#define HOST_IP inet_aton(argv[1], &ip)

sockaddr_in sockaddr;
sockaddr.sin_family = AF_INET;
sockaddr.sin_addr.s_addr = htonl(HOST_IP);
sockaddr.sin_port = htons(HOST_PORT);

以获取cli中的ip和端口号。然后我绑定,倾听,接受和阅读。

我确实编译了,当我使用./server localhost 8080时,一切都按预期工作。

但是,如果我使用./server 127.0.0.1 8080或./server 192.168.30.1 8080似乎是绑定和侦听,则没有错误,但我没有增强请求。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-06 21:54:19

你在滥用inet_aton()。

您将inet_aton()的返回值分配给您的sockaddr变量,而不是指定inet_aton()输出的in_addr结构。返回值不是IP地址!

inet_aton()在成功时返回非零值,在失败时返回0.换句话说,它的返回值基本上是一个布尔值。

使用IP地址bind() (又名INADDR_ANY)调用AF_INET会指示它将AF_INET套接字绑定到指定端口上的所有本地网络接口,这对于服务器来说非常常见(而且通常是首选的)。

调用inet_aton("localhost") 失败了,因为您不能将主机名传递给inet_aton(),所以它返回0,然后使用一个s_addr设置为INADDR_ANY的sockaddr_in对套接字进行bind(),这是可以的,因此您的代码似乎与"localhost"一起工作,但这只是侥幸。

调用inet_aton("127.0.0.1")或inet_aton("192.168.30.1") 继承了,因此它返回非零,然后使用一个s_addr设置为无效IP的sockaddr_in对套接字进行bind(),导致bind()要么彻底失败,要么绑定到与您预期不同的现有网络接口。

而且,in_addr输出的inet_aton()已经是网络字节顺序,因此不需要对其输出调用htonl()。

试一试:

代码语言:javascript
复制
struct in_addr ip;
#define HOST_PORT atoi(argv[2])
#define HOST_IP ((inet_aton(argv[1], &ip) != 0) ? ip.s_addr : 0)

struct sockaddr_in sockaddr;
memset(&sockaddr, 0, sizeof(sockaddr));
sockaddr.sin_family = AF_INET;
sockaddr.sin_addr.s_addr = HOST_IP;
sockaddr.sin_port = htons(HOST_PORT);

// use sockaddr as needed ...

或者,只需去掉您的HOST_IP和HOST_PORT宏,因为它们并不能真正帮助您:

代码语言:javascript
复制
struct sockaddr_in sockaddr;

memset(&sockaddr, 0, sizeof(sockaddr));
sockaddr.sin_family = AF_INET;
inet_aton(argv[1], &(sockaddr.sin_addr));
sockaddr.sin_port = htons(atoi(argv[2]));

// use sockaddr as needed ...

话虽如此,你真的应该使用getaddrinfo()来代替,例如:

代码语言:javascript
复制
struct addrinfo hints, *res;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;

if (getaddrinfo(argv[1], argv[2], &hints, &res) == 0)
{
    // use res->ai_addr and res->ai_addrlen with socket() and bind() as needed ...
    freeaddrinfo(res);
}

getaddrinfo()将为您将IP地址字符串和主机名字符串解析为适当的sockaddr_...结构,并将愉快地处理与本地主机相关的字符串,如"localhost"、"127.0.0.1"、"192.168.30.1"等。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62761866

复制
相关文章

相似问题

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