socket 套接字编程笔记——IP地址转换
来源:互联网 发布:传奇归来网络传输异常 编辑:程序博客网 时间:2024/06/05 07:18
0.前言
网上有很多使用arduion和树莓派连接yeelink的例子,硬件和软件的实现方式都非常简单。通过学习这些例子一下激发我学习嵌入式网络的动力。虽然使用arduion连接yeelink简单方便稳定可靠,但是依然像使用嵌入式以太网协议栈连接yeelink,例如MCU使用STM32,网卡芯片使用ENC28J60,以太网协议栈使用LwIP。虽然这样做硬件软件都要复杂的多,但是也多了不少“乐趣”。事情总是要循序渐进,我决定先认真研究socket编程,使用PC平台和yeelink交换数据。
1.测试环境说明
windows环境,编译器为minGW,IDE为eclipse。windows环境下的套接字编程和linux环境略有区别,但是基本的思路和方法相同。若使用minGW加eclipse的开发方式,需要加入wsock32库。添加的方法如下:
1.project -> properties
2.c/c++ build -> settting
3.tool setting -> mingw c linker -> libraries
4.add wsock32
图1 添加wsock32库
2.IP地址格式转换
通常情况下,IP地址都被写成以下格式:192.168.1.101或者10.13.11.105。这种形式的IP地址易于理解,但是对于协议处理来说就显得不是那么的方便,为了让IP地址更容易被处理并兼顾网络传输中的格式(网络传输为大端格式),所以定义了in_addr结构体:
struct in_addr {union {struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;struct { u_short s_w1,s_w2; } S_un_w;u_long S_addr;} S_un;#define s_addr S_un.S_addr#define s_host S_un.S_un_b.s_b2#define s_net S_un.S_un_b.s_b1#define s_imp S_un.S_un_w.s_w2#define s_impno S_un.S_un_b.s_b4#define s_lh S_un.S_un_b.s_b3};
在一些网上流传的套接字代码中,经常会看到这样的代码
struct in_addr server_addr
server_addr.s_addr = .....
此处的server_addr为一个in_addr类型结构体,server_addr代表一个IP地址。如果理解in_addr类型结构体,也就是把一个IP地址理解为4个字符,或2个16位长度整数,或1个32位长度的整数。由于in_addr类型结构体中包含一个共用体。为使编程更简便些可使用s_addr替代S_un.S_addr,所以便有了server_addr.s_addr这样的代码。in_addr类型结构体一般不单独出现(除了DNS地址解析外),而是存在于sockaddr_in结构体中,sockaddr_in可理解为套接字地址结构体。
3.格式之间的相互转换
ASCII形式的IP地址可以和整数形式的IP地址相互相关,在windows平台下可以使用inet_addr和inet_ntoa。
3.1 inet_addr
函数原型和输入输出参数
unsigned long inet_addr( _In_ const char *cp);
函数作用
把ASCII格式的IP地址(AAA.BBB.CCC.DDD形式)转换为一个32位无符号整数。
3.2 inet_ntoa
函数原型和输入输出参数
char* FAR inet_ntoa( _In_ struct in_addr in);
函数作用
把in_addr类型的IP地址转换为ASCII格式的IP地址(AAA.BBB.CCC.DDD形式)。inet_ntoa中的n可理解为network,a可理解为ascii。该函数一般用于打印IP地址。
4.示例代码
#include <winsock2.h>#include <ws2tcpip.h>#include <stdio.h>#include <string.h>#include <windows.h>int main(int argc, char **argv){ unsigned long addr = INADDR_NONE; // 测试inet_addr char server_ipaddr[] = {"192.168.1.101"}; addr = inet_addr( server_ipaddr); if ( addr == INADDR_NONE && addr == INADDR_ANY ) { printf("转换失败\n"); return 1; } // 转换结果(unsigned long)1694607552 printf("转换结果(unsigned long)%lu\n",addr); // 测试inet_itoa // 转化为ASCII字符串形式的IP地址 struct in_addr client_ipaddr; client_ipaddr.s_addr = addr; // 转换结果("XXX.XXX.XXX.XXX") 192.168.1.101 printf( "转换结果(\"XXX.XXX.XXX.XXX\") %s" , inet_ntoa( client_ipaddr ) ); return 0;}
运行结果
转换结果(unsigned long)1694607552
转换结果("XXX.XXX.XXX.XXX") 192.168.1.101
程序分析
首先准备一个ASCII形式的IP地址,例如192.168.1.101。使用inet_addr转换为一个32位无符号整数,转换结果为1694607552。保留该结果并在通过inet_ntoa还原192.168.1.101。还原之前需要先定义in_addr类型结构体,并命名为client_ipaddr,client_ipaddr.s_addr 为32位无符号整数可直接赋值。最后使用inet_ntoa对client_ipaddr变量进行格式转换并通过串口打印。
- socket 套接字编程笔记——IP地址转换
- java TCP/IP Socket编程-----基本套接字-----获取本机地址-----笔记3
- 套接字编程相关函数(套接字地址结构、字节序转换、IP地址转换)
- socket编程学习(二)地址转换与套接字
- 六、Linux网络编程-socket、套接字地址结构、地址转换、字节序、套接字类型
- 1.socket编程:socket编程,网络字节序,函数介绍,IP地址转换函数,sockaddr数据结构,网络套接字函数,socket相关函数,TCP server和client
- 1.socket编程:socket编程,网络字节序,函数介绍,IP地址转换函数,sockaddr数据结构,网络套接字函数,socket相关函数,TCP server和client
- java TCP/IP Socket编程-----基本套接字-----TCP套接字通讯-----笔记5
- TCP/IP网络编程 学习笔记_3 --给套接字分配IP地址和端口号
- 网络编程——Socket(套接字)
- 【网络编程学习笔记01】Socket套接字编程(TCP/IP)
- (四十八)socket编程——引入、网络字节序、IP地址转换函数、sockaddr数据结构
- 网络编程笔记一、Socket套接字
- java TCP/IP Socket编程-----基本套接字-----常用API方法解释-----笔记4
- java TCP/IP Socket编程-----基本套接字-----UDP通讯-----笔记6
- 套接字—Socket
- Socket套接字编程(一)——TCP编程
- Socket套接字编程(二)——UDP编程
- UVA 10721Bar Codes(dp)
- POJ 3683 Priest John's Busiest Day (2 - SAT) - from lanshui_Yang
- 利用nfs挂在根文件系统
- linux下mysql数据库的rpm安装步骤及常见问题的解决
- python项目练习九:文件共享2-GUI版本
- socket 套接字编程笔记——IP地址转换
- Spring中BeanFactory、ApplicationContext区别
- python项目练习十:DIY街机游戏
- Linux之TCP/IP
- 网络协议
- Java.lang.NoClassDefFoundError: javax/servlet/http/HttpServlet解决办法
- DMA映射 dma_addr_t
- Linux嵌入式工程师成长经历
- callback函数