欢迎使用CSDN-markdown编辑器

欢迎光临南窗雨的博客

以前试验过同一个端口号,同一个IP地址,如果创建的socket套接字不是同一个协议的也是可以创建成功的。现在想了解一下,如果是服务器使用同一个端口号,同一个协议,不同的IP地址的情况下能否成功,理论上将应该是可以成功的,但是作为一个有理想的程序员还是不能够说瞎话的,还是要靠事实来证明的。

以前写的代码都是这个样子的

listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(56600);

lRet = bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

使用socket函数来创建监听套接字,选择一下是IPV4还是IPV6,选择是UDP还是TCP协议。
这边选择的IP地址就是INADDR_ANY,这个是一个宏定义,它的值是0,0是binary form,它转换成 numbers-and-dots notation,就是0.0.0.0。而0.0.0.0代表着什么呢?这个代表着本机的所有IP,也就是说它可能代表你本机上的127.0.0.1和192.168.1.100,甚至更多的IP地址,当绑定0.0.0.0这个IP地址以后,在56600上面接收到的消息想所有的IP地址都会发送。我们现在想测试的是同一个端口,不同IP,这个时候肯定是不可以选择INADDR_ANY,需要指定IP地址,这个时候代码就需要改成这样的。

lRet = inet_aton("127.0.0.1", (struct in_addr *)&hostaddr);
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(hostaddr.s_addr);
servaddr.sin_port = htons(56600);
Ret = bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

代码改成这样以后编译可以通过没有语法问题,但是执行的时候会报错,看errno的值得到的信息是Cannot assign requested address,看不懂什么意思,找度娘也是有各种答案,但跟我的现象好像也不是一样的。只能靠我们自己来定位了。

在尝试了将代码改成如下:

listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(56600);

改成这样以后,就可以正常执行了,那原来的为什么无法正常执行呢
通过man这个命令我们知道了,inet_aton和inet_addr这两个函数返回的已经是网络序了(关于什么是网络序,什么是本机序,看官请自行百度。)

现在我们知道了原来会报Cannot assign requested address的原因是因为我们将hostaddr.s_addr的结果又通过htonl进行了字节序转换,转换后的ip地址又是我们所没有的,因此就会报这个Cannot assign requested address。

我们在来深入一点,为什么在有了inet_addr的情况下还需要inet_aton,或者说是这两个函数有什么区别。我所了解到的他们的区别是
inet_addr无法识别”255.255.255.255”,而inet_aton可以识别。
看官们可以思考一下”255.255.255.255”转换成数字是什么呢?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值