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.2inet_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 套接字 Java 套接字 编程 socket 套接字 Java 套接字 编程 socket 套接字 Java 套接字 编程 socket 套接字 Java 套接字 编程
基于Java的Socket套接字编程 源代码
Socket套接字—Java套接字编程
网络编程中,通常使用socket套接字编程,那么该如何使用呢?接下来我们做一个最基本的小程序实现其功能。博客地址:http://blog.csdn.net/bingdianlanxin,有问题欢迎留言!
JAVA网络编程资料(1)-Socket套接字—Java套接字编程.chm
socket 套接字编程介绍socket 套接字编程介绍
网络socket套接字编程服务器客户端程序 精心写好的socket通信程序,实现服务器同时接受多个连接! 效果类似于ftp登录时的欢迎信息 使用正确的用户和密码登录后会看到服务器发送回来的欢迎信息! 这只是一个初稿,...
socket套接字编程,使用vc++的控制台编程实现tcp的服务器与客户端,程序简单,初学者可以看看= w =~
Socket即套接字 java.net包的客户端Socket,服务端ServerSocket; 单线程套接字客户端和服务端的处理; 服务端多线程处理客户端套接字; 带有线程池处理客户端套接字; 不会Socket,有Java基础就能完全理解Socket...
C++实现的基于Socket套接字的编程。能够能够单线程处理一个请求。能够实现经TCP连接向请求的浏览器发送响应,浏览器可以正确显示网页的内容。
关于socket套接字的编程视频,内容详细,非常适合新手学习,还在等什么呢,快来观看吧。
Socket套接字—Java套接字编程(上1)
socket套接字的编程原理(里面有代码举例),可以参照学习socket编程。是很好的入门教材
套接字是由美国伯克利大学提出并设计的一种在网络中不同主机之间进行数据交换的通信桥梁。在实际生活中,人们所使用的网络通讯软件功能均是基于Socket...本章将向用户介绍使用Socket套接字编程的相关概念以及实现方法。
客户机/服务器模式 在TCP/IP网络中两个进程间的相互作用的主机模式是客户机/服务器模式
Windows Socket 套接字编程原理(Word文件)
28_网络编程(Socket套接字编程)_讲义
C++基于QT与Socket套接字的邮件系统实现源码。基于QT与Socket套接字的邮件系统实现 主要实现前端界面,后端数据库,以及Csocket套接字实现通信。运行环境:Windows10 + QT 前端: Qt项目工程,呈现界面,负责处理与...
详细描绘C++中使用套接字编程实现TCP/IP通信