socket编程中htonl和htons深入探讨
socket编程中htonl和htons深入探讨
- 背景:
- 问题分析和解决:
- 深入分析:
背景:
在socket编程中遇到一个错误:server端设置端口和ip时,使用htonl函数。然后client死活无法连接,一致报错
connect error: Connection refused(errno:111)
问题代码:
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htonl(6666);
问题分析和解决:
刚开始,一再检查代码逻辑,也在网上找了一些资料,按照一些方法作了修改,但是问题依然无法解决。(其实是想偷懒。呵呵)
后来将"htonl(666)"改为"htons(666)"程序运行正确了,client可以连接上。但是一直想不通为什么使用htonl不可以,非要使用htons呢。
修改后的代码:
serveraddr.sin_addr.s_addr = htons(INADDR_ANY);
serveraddr.sin_port = htons(6666); //unsigned short类型,即16位,因为端口一般的取值范围是0~65536
深入分析:
(1)为什么htons(6666)时,serveraddr.sin_port值为2586?
经过gdb单步调试,发现使用htonl时候,serveraddr.sin_port的值为0,使用htons时候,serveraddr.sin_port的值为2586。
unsigned short类型的6666为10进制,用16进制表示为:0x1A0A,在机器(小端序)内存中存放顺序为0x0A 0x1A;十进制:unsigned 6666十六进制:0x1A0A,总共两个字节,高位字节为0x1A,低位字节为0x0A。主机CPU是小端序(大部分CPU都是小端序的,即低字节在前,高字节在后),内存里的顺序为:0x0A1A但是,经过htons转换后,高低字节变换了,变为大端序:0x0A1A,即A1A,对应十进制就是2586。此时,内存里的顺序(还是小端序的CPU)就成了:0X1A0A。由于转换后,内存里的值变了。打印出来自然就是不一样了(6666变成了2586)。
好了,这就理解了6666为什么经过htons转换后就成了2586。
(上面这一段也不知道怎么排版和调整字体才好看,就弄成这样了。。)
(2)为什么htonl(6666)时,serveraddr.sin_port值为0?
接下来看看为什么使用htonl转换结果就是0呢?
十进制:unsigned int 6666,32位,4个字节十六进制:0x00001A0A,总共4个字节,高位字节--->低位字节依次是:0x00 0x00 0x1A 0x0A经htonl转换为大端序后为:0x0A 0X1A 0X00 0X00,即0x0A1A0000,对应十进制就是169476096。
那么为什么serveraddr.sin_port值是0而不是169476096?
前面说了,serveraddr.sin_port是unsigned short类型(可以在netinet/in.h或arpa/inet.h中查看)。unsigned short的范围是0~65535,很显然无法容纳169476096。
unsigned int: 16947609616进制:0x0A1A00002进制:0000 1010, 0001 1010, 0000 0000, 0000 0000将htonl(6666)的值(169476096)赋值给serveraddr.sin_port时候,由于serveraddr.sin_port是unsigned short类型,会进行隐式类型转换:
将unsigned int类型的169476096强转为unsigned short时,会做截断处理:
截掉了前面两个高位字节,剩下两个低位字节:0000 0000, 0000 0000 即为0,然后将该值赋给serveraddr.sin_por。所以gdb时候看到serveraddr.sin_por的值为0。但是使用%d单独printf输出htonl(6666)时候值为0。至于为什么截断高位字节,只保留低位字节,可能是C语言设计的处理规则吧。
现在两个问题已经搞明白了。还有一点提醒就是,
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); //unsigned int类型,即32位ip地址,这里将主机的无符号长整型数转换成网络字节顺序
// serveraddr.sin_addr.s_addr = htons(INADDR_ANY); //也可以使用htonl替换htons,测试没发现报错,但是最好使用htonl,毕竟类型保持一致
现在两个问题已经搞明白了。还有一点提醒就是:
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); //unsigned int类型,即32位ip地址,这里将主机的无符号长整型数转换成网络字节顺序
// serveraddr.sin_addr.s_addr = htons(INADDR_ANY); //也可以使用htonl替换htons,测试没发现报错,但是最好使用htonl,毕竟类型保持一致
(3)端口说明:
端口号:
对于BSD:
1-1023:BSD保留端口。
1024-5000:BSD临时端口。
5001-65535:BSD服务器(非特权)
socket编程中htonl和htons深入探讨相关推荐
- IP地址的三种表示格式及在Socket编程中的应用
转自:http://blog.csdn.net/hguisu/article/details/7449955 使用TCP/IP协议进行网络应用开发的朋友首先要面对的就是对IP地址信息的处理.IP地址其 ...
- IP地址的三种表示格式 及 在Socket编程中的应用
关于windows中的INADDR_ANY这个宏 头文件winsock.h中定义#define INADDR_ANY (u_long)0x00000000 它是用于多IP机器 ...
- SOCKET编程中,select()函数的作用
SOCKET编程中,select()函数的作用Select在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只是习惯写诸如connect.accep ...
- socket编程中常见的概念问题!
socket编程一般指的就是网络编程,常见的服务端和客户机都是必不可少的,今天小千就来给大家介绍一下socket编程中常见的概念问题. 一.常见传输协议 1.tcp协议 TCP (Transmissi ...
- socket编程中read()、write()、recv()和send()
Muduo 网络编程示例之八:用 Timing wheel 踢掉空闲连接 - 陈硕 - 博客园socket编程中read().write().recv()和send()的区别_John W ...
- TCP与UDP在socket编程中的区别
TCP与UDP在socket编程中的区别 一.TCP与UDP的区别 基于连接与无连接 对系统资源的要求(TCP较多,UDP少) UDP程序结构较简单 流模式与数据报模式 TCP保证数据正确性,UDP可 ...
- C语言socket编程中关于read()和write()的思考
最近开始学习C的socket编程,教材上有一处依照我对IO函数的理解,我感觉有点问题,故而研究了一下.学的很浅,可能有错漏. 1.socket编程中read()和write()内部原理 每个socke ...
- TCP的socket编程中“全双工的字节流”含义的深刻理解
本人从事TCP的socket编程多年,趟过很多坑,对于TCP是"全双工的字节流"这几个字的含义有深刻理解.这几个字,文字虽少,但字字精辟.如果没有深刻理解,编程中可能知其然不知其所 ...
- socket编程中的 htons()
文章目录 1.内存存储数据的方式 1.1 数据字节序号 1.2 小端字节序 1.3 大端字节序 2. 转换顺序 2.1 网络字节序 2.2 主机字节序 2.3 转换函数 在刚刚接触 socket ...
最新文章
- 数据的存入取出(注册机方式)
- 用python写一个简单的爬虫_Python实现简易Web爬虫详解
- 1.Hadoop初步环境搭建(ssh无密码通信)
- Linux文件系统映像:Initranfs 和 Initrd
- 七大排序算法的个人总结(二)
- 网站打开速度多少毫秒为正常_诠网科技|网站优化中跳出率多少才是合理的?...
- python调用其他文件中的函数或者类
- android sdio 时钟 ios-clock,iOS 炫酷时钟
- c# redis 如何设置过期时间_Redis 过期时间与内存管理
- python中常见的运行时错误_新手常见Python运行时错误汇总
- angular ts 表格_angular+ng-zorro路由、表格组件
- C++11 修复了双重检查锁定问题(转)
- 在线火星文转换器工具
- linux内存手动释放
- FileZilla Server目录显示失败的处理方法
- HDU 5773 (DP)
- 华为系统和计算机,电脑手机合二为一 华为多屏协同让电脑与手机亲密互动
- mysql大于等于between比较_MySQL范围查询优化,Between与大于等于对比及优化
- Unity中加载倾斜摄影模型、dem叠加卫星影像做真实地形
- C语言实现复数计算器