用phpmysql做图书网站,深圳企业排名,郑州网站建设庄园,wordpress 局域网访问网络协议栈LwIP WiFi UDP Clinet编程 WiFi UDP Server编程 WiFi TCP Client编程 WiFi TCP Server编程 一。LWIP原理介绍#xff0c;API介绍#xff0c;文件结构
1.Lwip支持的协议 2.API 3.文件结构 1.api目录#xff1a;应用程序接口文件。 2.arch目录#xff1a;与硬件和… 网络协议栈LwIP WiFi UDP Clinet编程 WiFi UDP Server编程 WiFi TCP Client编程 WiFi TCP Server编程 一。LWIP原理介绍API介绍文件结构
1.Lwip支持的协议 2.API 3.文件结构 1.api目录应用程序接口文件。 2.arch目录与硬件和OS有关的文件包括网络驱动、移植需要修改的文件。 3.core目录LwIP的核心代码包括ICMP、IP、UDP、TCP等协议的实现等。 4.include目录LwIP的包含文件。 5.netif目录PPP协议和LwIP网络设备驱动程序的模板提供了网络接口驱动程序的基本框架。 4.Socket 通信模型 Socket是一个网络编程接口 Socket类型 1流式套接字(SOCK_STREAM) 2数据报套接字(SOCK_DGRAM) 3原始套接字(SOCK_RAW) 5.Socket API socket创建一个套接字 bind将本地端口号和IP地址绑定到套接字上 listenTCP监听 acceptTCP监听接受处理 connectTCP客户端连接 select特殊套接字设置 send/sendto发送数据包到已连接/未连接套接字上 recv/recvfrom接收数据包从已连接/未连接套接字上 getsockopt/setsockopt获取/改变套接字选项 getpeername/getsockname获取远端/本地地址信息 close关闭套接字 shutdown按设置关闭套接字 gethostbyname/gethostbyaddr地址域名映射 read从套接字缓存读数据 write向套接字缓存写数据 目的 Lwip协议栈的实现目的无非是要上层用来实现app的socket编程。 为了兼容性lwip的socket通过宏定义提供标准的socket接口函数 5.介绍常用的API
1int socket (int domain, int type, int protocol); 1.domain 是地址族 PF_INET // internet IPv4协议 PF_INET6 // internet IPv6协议 PF_UNSPEC // 用户协议 2.type // 套接字类型 SOCK_STREAM // 流式套接字 SOCK_DGRAM // 数据报套接字 S OCK_RAW // 原始套接字 3.protocol //参数通常置为0 IPPROTO_IP 0 IPPROTO_TCP 6 IPPROTO_UDP 17 2int bind (int sockfd, struct sockaddr* addr, int addrLen); 1.sockfd 由socket() 调用返回 2.addr 是指向 sockaddr_in 结构的指针包含本机IP 地址和端口号 struct sockaddr_in{ u_short sin_family // protocol family u_short sin_port // port number } struct in_addr sin_addr //IP address (32-bits) 3.addrLen : sizeof (struct sockaddr_in) 3地址结构
地址的数据结构
通用地址结构struct sockaddr{ u_short sa_family; // 地址族, AF_xxxchar sa_data[14]; // 14字节协议地址};Internet协议地址结构struct sockaddr_in{ u_short sin_family; // 地址族, AF_INET2 bytesu_short sin_port; // 端口2 bytesstruct in_addr sin_addr; // IPV4地址4 bytes char sin_zero[8]; // 8 bytes unused作为填充};
IPv4地址结构
// internet address
struct in_addr
{in_addr_t s_addr; // u32 network address
};使用方法 1.定义一个struct sockaddr_in类型的变量并清空 struct sockaddr_in myaddr;
memset(myaddr, 0, sizeof(myaddr)); 2.填充地址信息 myaddr.sin_family PF_INET;
myaddr.sin_port htons(8888);
myaddr.sin_addr.s_addr inet_addr(“192.168.1.100”); 3.将该变量强制转换为struct sockaddr类型在函数中使用 bind(listenfd, (struct sockaddr*)(myaddr), sizeof(myaddr));4地址转换函数
1.unsigned long inet_addr(char *address); address是以’\0’结尾的点分IPv4字符串。该函数返回32位的地址。如果字符串包含的不是合法的IP地址则函数返回-1。例如 struct in_addr addr
addr.s_addr inet_addr( 192.168.1.100 ); 2.char* inet_ntoa(struct in_addr address); address是IPv4地址结构函数返回一指向包含点分IP地址的静态存储区字符指针。如果错误则函数返回NULL。 5获取/发送套接字
获取套接字
int getsockopt(int sock, int level,int optname, void *optval, socklen_t *optlen);发送套接字
int setsockopt(int sock, int level,int optname, const void *optval, socklen_t optlen);参数 sock将要被设置或者获取选项的套接字。 level选项所在的协议层。 optname需要访问的选项名。 optval对于getsockopt()指向返回选项值的缓冲。对于setsockopt()指向包含新选项值的缓冲。 optlen对于getsockopt()作为入口参数时选项值的最大长度。作为出口参数时选项值的实际长度。对于setsockopt()现选项的长度。 返回说明 成功执行时返回0。 失败返回-1errno被设为以下的某个值 EBADFsock不是有效的文件描述词 EFAULToptval指向的内存并非有效的进程空间 EINVAL在调用setsockopt()时optlen无效 ENOPROTOOPT指定的协议层不能识别选项 ENOTSOCKsock描述的不是套接字 6listen监听
int listen (int sockfd, int backlog);sockfd:监听连接的套接字。 backlog 指定了正在等待连接的最大队列长度它的作用在于处理可能同时出现的几个连接请求。 DoS(拒绝服务)攻击即利用了这个原理非法的连接占用了全部的连接数造成正常的连接请求被拒绝。 返回值 0 或 -1。 完成listen()调用后socket变成了监听socket(listening socket). 7accept
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) ;返回值已建立好连接的套接字或-1 sockfd : 监听套接字 addr : 对方地址 addrlen地址长度 8connect
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);返回值0 或 -1 sockfd : socket返回的文件描述符 serv_addr : 服务器端的地址信息 addrlen : serv_addr的长度 9send/sendto
ssize_t send(int socket, const void *buffer, size_t length, int flags);
ssize_t sendto(int s, const void *data, size_t size, int flags,const struct sockaddr *to, socklen_t tolen);返回值 成功实际发送的字节数 失败-1, 并设置errno 头文件 #include sys/socket.h buffer : 发送缓冲区首地址 length : 发送的字节数 flags : 发送方式通常为0 10recv/recvfrom
ssize_t recv(int socket, const void *buffer, size_t length, int flags);
ssize_t recvfrom(int s, void *mem, size_t len, int flags,struct sockaddr *from, socklen_t *fromlen);返回值 成功实际接收的字节数 失败-1,并设置errno buffer : 发送缓冲区首地址 length : 发送的字节数 flags : 接收方式通常为0 11套接字关闭
int close(int sockfd);
int shutdown(int sockfd, int howto);close是双向通信的关闭 TCP连接是双向的(是可读写的)当我们使用close时,会把读写通道都关闭有时侯我们希望只关闭一个方向这个时候我们可以使用shutdown。针对不同的howto系统回采取不同的关闭方式。 howto 0 关闭读通道但是可以继续往套接字写数据。 howto 1 和上面相反关闭写通道。只能从套接字读取数据。 howto 2 关闭读写通道和close()一样 二。实验WiFi UDP Clinet编程
1.功能分析 完成UDP Client功能开发 1PC模拟UDP Server指定IPPORT等待Client数据 2UDP Client向Sever发送“I am Client!” 3Sever收到数据后向Client发送“I am Server!” 2.功能实现 1在SDK目录下新建udpclient目录 2拷贝Station目录下所有文件到udpclient目录下 3在user目录下新建udpclient.c 4在include目录下新建udpclient.h 1Sourceinsight配置 在之前的工程中移除AP文件夹 添加udpclient文件夹 添加lwip文件夹 同步 发现的问题 QQ的截屏比SourceInsight复制优先级低即先复制代码在截屏之后粘贴还是复制的代码 3.代码实现 1.在udpclient.c下添加《整体复制粘贴》 1udpclient初始化 2udpclient任务 #include esp_common.h#include freertos/FreeRTOS.h
#include freertos/task.h#include lwip/sockets.h
#include lwip/dns.h
#include lwip/netdb.h
#include udpclient.h#define SERVERADDR 192.168.3.12//注意这是wifi分配的ip地址会变化
#define SERVERPORT 8000
/******************************************************************************* FunctionName : ATaskUdpClient* Description : ATaskUdpClient 任务* Parameters : none* Returns : none
*******************************************************************************/
void ATaskUdpClient( void *pvParameters )
{int iVariableExample 0;int fd -1;int NetTimeOnt 5000;int ret;struct sockaddr_in ServerAddr;char udpmsg[48];STATION_STATUS StaStatus;do {StaStatus wifi_station_get_connect_status();vTaskDelay(100);}while(StaStatus ! STATION_GOT_IP);fd socket(PF_INET,SOCK_DGRAM,0);if(fd -1){printf(get socket fail!\n);vTaskDelete(NULL);}setsockopt(fd,SOL_SOCKET,SO_RCVTIMEO,NetTimeOnt,sizeof(int));memset(ServerAddr,0,sizeof(ServerAddr));ServerAddr.sin_family AF_INET;ServerAddr.sin_addr.s_addr inet_addr(SERVERADDR);ServerAddr.sin_port htons(SERVERPORT);ServerAddr.sin_len sizeof(ServerAddr);for(;;){sendto(fd,I am UdpClient!,sizeof(I am UdpClient!),0,(struct sockaddr *)ServerAddr,(socklen_t)ServerAddr.sin_len);do{ret recvfrom(fd,udpmsg,48,0,(struct sockaddr *)ServerAddr,(socklen_t*)(ServerAddr.sin_len));if(ret 0){printf(UdpServer:%s\n,udpmsg);}else{printf(UdpServer data is no!\n);}}while(ret -1);}vTaskDelete( NULL );
}
/******************************************************************************* FunctionName : UdpClient_init* Description : UdpClient_init 初始化* Parameters : none* Returns : none
*******************************************************************************/
void UdpClient_init(void)
{xTaskCreate(ATaskUdpClient, UdpClient, 256, NULL, 4, NULL);
} 注意上述的IPv设置的是本机的IP地址 WinR---》cmd进入命令行 输入ipconfig查询无线网络ipv4地址 对上述代码的解释 1判断是否获取到IP地址 2创建socket 3设置接收超时时间 4赋值server信息 5发送数据到server端 6从server端接收数据 2.在udpclient.h下声明《整体复制》 #ifndef __UART_H__
#define __UART_H__#ifdef __cplusplus
extern C {
#endifvoid ATaskUdpClient( void *pvParameters );
void UdpClient_init(void);#ifdef __cplusplus
}
#endif#endif3.在user_main中 UdpClient_init(); 5.运行方式 1创建一个UDPip为本机被分配的无线ipv4地址端口为程序代码设置的端口 查询IP地址通过ipconfig命令获取本机ip地址 2建立串口通讯波特率为74880关闭RTS使用终端模式 4.结果 1串口中打印从UDP服务器传输过来的数据123 三。实验WiFi UDP Server编程
1.功能分析 实验要求 完成UDP Server功能开发 1.PC模拟UDP Client指定UDP Server IPPORT发送“I am Client!” 2.Sever收到数据后向Client发送“I am Server!” 2.功能实现
新建udpserver工程目录 1.在SDK目录下新建udpserver目录 2.拷贝udpclient目录下所有文件到udpserver目录下 新建udpserver源码文件 1.在user目录下新建udpserver.c 2.在include目录下新建udpserver.h Sourceinsight配置 1.在之前的工程中移除udpclient文件夹 2.添加udpserver文件夹 3.代码实现 1.复制之前udpclient代码到udpserver上进行修改 1重命名UdpClient_init为UdpServer_init 2重命名ATaskUdpClient为ATaskUdpServer 2.修改user_main.c 1包涵udpserver.h 2在user_init里修改为UdpServer_init 代码的详细解释 1.判断是否获取到IP地址 2.创建socket 3.Serveraddr 信息设置 4.设置接收超时时间 5.绑定socket 6.从Client端接收数据 7.发送数据到Client端 结果
四。WiFi TCP Client编程
1.功能分析 实验要求 完成TCP Client功能开发 1.PC模拟TCP Server指定IPPORT等待Client数据 2.TCP Client向Sever发送“I am Client!” 3.Sever收到数据后向Client发送“I am Server!” 2.功能实现
新建tcpclient工程目录 1.在SDK目录下新建tcpclient目录 2.拷贝udpclient目录下所有文件到tcpclient目录下 新建tcpclient源码文件 1.在user目录下新建tcpclient.c 2.在include目录下新建tcpclient.h Sourceinsight配置 1.在之前的工程中移除udpserver文件夹 2.添加tcpclient文件夹 3.代码实现 1.复制之前udpclient代码到tcpclient上进行修改 1重命名UdpClient_init为TcpClient_init 2重命名ATaskUdpClient为ATaskTcpClient 2.修改user_main.c 1包涵tcpclient.h 2在user_init里修改为TcpClient_init 代码详细解释 1.判断是否获取到IP地址 2.创建socket 3.设置接收超时时间 4.赋值server信息 5.连接到server端 6.发送数据到server端 7.从server端接收数据 五。实验WiFi TCP Server编程
1.功能分析 实验要求 完成TCP Server功能开发 1.PC模拟TCP Client指定ServerIPPORT 1进行连接连接成功后发生“I am Client!” 2Sever收到数据后向Client发送“I am Server!” 2.功能实现
新建tcpserver工程目录 1.在SDK目录下新建tcpserver目录 2.拷贝tcpclient目录下所有文件到tcpserver目录下 新建tcpserver源码文件 1.在user目录下新建tcpserver.c 2.在include目录下新建tcpserver.h Sourceinsight配置 1.在之前的工程中移除tcpclient文件夹 2.添加tcpserver文件夹 3.代码实现 1.复制之前tcpclient代码到tcpserver上进行修改 1重命名TcpClient_init为TcpServer_init 2重命名ATaskTcpClient为ATaskTcpServer 2.修改user_main.c 1包涵tcpserver.h 2在user_init里修改为TcpServer_init 代码详解 1.判断是否获取到IP地址 2.创建socket 3.设置接收超时时间 4.赋值server信息 5.绑定socket 6.监听socket 7.处理Client 连接 8.接收Client 数据 9.发送数据到Server 10.关闭socket