先简略记录。
安装软件的时候发现一直提示这个错误,因此在源代码加入printf打印语句将ip port打印出来看看究竟是啥导致已被使用的。打印语句是:
char *ip = inet_ntoa(((struct sockaddr_in*)&server)->sin_addr);
printf("ip: %s\n", ip);
printf("port: %u\n", ((struct sockaddr_in*)&server)->sin_port);
打印出来我的端口是13134,使用netstat查看后发现这个端口并没有被监听(建议多执行几次,若端口有变化,说明没有被初始化,若没有变化,那就是冲突了)
第一次查socket,一度让人费解(错误的太低级,导致百度不到相同的问题),这个时候灵感来了(对象的灵感哈哈哈);socket是有大端和小端的,那我根据上面
语句打印的时候是个什么顺序呢(也是对函数的陌生啊),会不会打印反了呢。可以用两个方法进行验证;
方法一 使用ntohs函数
ntohs函数会将一个16位数由网络字节顺序转换为主机字节顺序;将一个无符号短整型数从网络字节顺序转换为主机字节顺序;
char *ip = inet_ntoa(((struct sockaddr_in*)&server)->sin_addr);
printf("ip: %s\n", ip);
printf("port: %u\n", ((struct sockaddr_in*)&server)->sin_port);
printf("ntohs(port): %d\n", ntohs(((struct sockaddr_in*)&server)->sin_port));
ps: 标准库中封装的port就是一个无符号短整型(struct sockaddr_in{unsigned short int sin_port})
输出结果为:
ip: 0.0.0.0
port: 13134
ntohs(port): 20019
根据netstat在查看下20019端口就可以啦~
方法二 手动计算
由于打印port的时候我们并没有指定port转换为主机顺序, 所以我们得到的并不是一个主机字节,这就尴尬了,但对于我的需求来讲,我只需要知道这个port是啥,源码需不需要打印主机字节就无所谓了,那么最快速的方式就是: 计算器哈哈哈哈哈哈哈,我们手动算 (可以查看socket大端序列与小端序列的使用) 。
第一步 十进制转十六进制并修改顺序
输入十进制的13134(inet_ntoa转换后打印出来的),得到十六进制(HEX)的334E;然后将HEX前后顺序换一下,得到: 4E33;
第二步 十六进制转十进制
计算器中点击HEX,然后输入4E33,找到十进制(DEC)的结果
第三步 查看端口是否被使用
完事,事情的解决总是透露着兴奋与尴尬