3.wifi开发【网络编程1】WiFi UDP Clinet编程,WiFi UDP 编程,WiFi TCP Client编程,WiFi TCP Server编程

网络协议栈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地址绑定到套接字上

listen:TCP监听

accept:TCP监听接受处理

connect:TCP客户端连接

select:特殊套接字设置

send/sendto:发送数据包到已连接/未连接套接字上

recv/recvfrom:接收数据包从已连接/未连接套接字上

getsockopt/setsockopt:获取/改变套接字选项

getpeername/getsockname:获取远端/本地地址信息

close:关闭套接字

shutdown:按设置关闭套接字

gethostbyname/gethostbyaddr:地址域名映射

read:从套接字缓存读数据

write:向套接字缓存写数据

目的:

Lwip协议栈的实现目的,无非是要上层用来实现app的socket编程。 为了兼容性,lwip的socket通过宏定义提供标准的socket接口函数

5.介绍常用的API

(1)int 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

(2)int 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_xxx
       char  sa_data[14];     // 14字节协议地址
  };

Internet协议地址结构
  struct sockaddr_in
  {           
       u_short sin_family;      // 地址族, AF_INET,2 bytes
       u_short sin_port;      // 端口,2 bytes
       struct 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。

失败返回-1,errno被设为以下的某个值

EBADF:sock不是有效的文件描述词

EFAULT:optval指向的内存并非有效的进程空间

EINVAL:在调用setsockopt()时,optlen无效

ENOPROTOOPT:指定的协议层不能识别选项

ENOTSOCK:sock描述的不是套接字

(6)listen监听

int listen (int sockfd, int backlog);

sockfd:监听连接的套接字。

backlog 指定了正在等待连接的最大队列长度,它的作用在于处理可能同时出现的几个连接请求。 DoS(拒绝服务)攻击即利用了这个原理,非法的连接占用了全部的连接数,造成正常的连接请求被拒绝。 返回值: 0 或 -1。

完成listen()调用后,socket变成了监听socket(listening socket).

(7)accept

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) ;

返回值:已建立好连接的套接字或-1
sockfd : 监听套接字 
addr : 对方地址
addrlen:地址长度

(8)connect

int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);

返回值:0 或 -1

sockfd : socket返回的文件描述符

serv_addr : 服务器端的地址信息  

addrlen : serv_addr的长度

(9)send/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)

(10)recv/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功能开发

(1)PC模拟UDP Server,指定(IP,PORT),等待Client数据

(2)UDP Client向Sever发送“I am Client!”

(3)Sever收到数据后,向Client发送“I am Server!”

2.功能实现

(1)在SDK目录下新建udpclient目录

(2)拷贝Station目录下所有文件到udpclient目录下

(3)在user目录下新建udpclient.c

(4)在include目录下新建udpclient.h

(1)Sourceinsight配置

在之前的工程中,移除AP文件夹 添加udpclient文件夹

添加lwip文件夹

同步:

发现的问题:

QQ的截屏比SourceInsight复制优先级低,即先复制代码,在截屏之后粘贴还是复制的代码

3.代码实现

1.在udpclient.c下,添加《整体复制粘贴

(1)udpclient初始化

(2)udpclient任务

#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地址

Win+R---》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" {
#endif

void ATaskUdpClient( void *pvParameters );
void UdpClient_init(void);

#ifdef __cplusplus
}
#endif

#endif

3.在user_main中

UdpClient_init();

5.运行方式

(1)创建一个UDP,ip为本机被分配的无线ipv4地址,端口为程序代码设置的端口

查询IP地址(通过ipconfig命令获取本机ip地址

(2)建立串口通讯,波特率为74880,关闭RTS,使用终端模式

运行的注意事项:连接时间比较久,稍微等一下。

        我们使用了上一节wifi入网的代码,即wifi模块加入其他网络,这里的网络必须使用4G网络,5G我的esp8266不支持。

判断esp8266是否支持5G的方法:

        查看esp8266核心芯片的ISM为多少,2.4GHZ表示只支持4G网络,如果支持5G,器件会自己标注出来。

4.结果

(1)串口中打印从UDP服务器传输过来的数据(123)

三。实验:WiFi UDP Server编程

1.功能分析

实验要求:
完成UDP Server功能开发

1.PC模拟UDP Client,指定UDP Server (IP,PORT),发送“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.同步文件

3.代码实现

1.udpserver.h

#ifndef __UDPSERVER_H__
#define __UDPSERVER_H__

#ifdef __cplusplus
extern "C" {
#endif

void ATaskUdpServer( void *pvParameters );
void UdpServer_init(void);

#ifdef __cplusplus
}
#endif

#endif

2.udpserver.c

#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 "udpserver.h"

#define SERVERADDR "192.168.31.158"
#define SERVERPORT 8000

/******************************************************************************
 * FunctionName : ATaskUdpServer
 * Description  : ATaskUdpServer 任务
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ATaskUdpServer( void *pvParameters )
{
    int iVariableExample = 0;
    int fd = -1;

    int NetTimeOnt = 5000;
    int ret;

    struct sockaddr_in ServerAddr;
    struct sockaddr from;
    socklen_t fromlen = sizeof(struct sockaddr);
    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);
        return;
    }

    setsockopt(fd,SOL_SOCKET,SO_RCVTIMEO,&NetTimeOnt,sizeof(int));

    memset(&ServerAddr,0,sizeof(ServerAddr));
    ServerAddr.sin_family = AF_INET;
    ServerAddr.sin_addr.s_addr = INADDR_ANY;
    ServerAddr.sin_port = htons(SERVERPORT);
    ServerAddr.sin_len = sizeof(ServerAddr);

    if(bind(fd,(struct sockaddr*)&ServerAddr,ServerAddr.sin_len) != 0)
    {
    
        printf("bind socket fail!\n");
        vTaskDelete(NULL);
        return;
    }
    
    for(;;){

        do{
            ret = recvfrom(fd,udpmsg,48,\
               0,&from,&fromlen);
            if(ret > 0){

                printf("UdpClient:%s\n",udpmsg);
            }
            else            {
                printf("UdpClient data is no!\n");
            }
         }while(ret == -1);         
        sendto(fd,"I am UdpServer!",sizeof("I am UdpServer!"),\
               0,&from,fromlen);            
    }
    vTaskDelete( NULL );
}

/******************************************************************************
 * FunctionName : UdpServer_init
 * Description  : UdpServer_init 初始化
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void UdpServer_init(void)
{
    xTaskCreate(ATaskUdpServer, "UdpServer", 256, NULL, 4, NULL);
}

主函数修改

1.加入udp服务器头文件

2.user初始化函数中加入udp服务器初始化

代码的详细解释

1.判断是否获取到IP地址

2.创建socket

3.Serveraddr 信息设置

4.设置接收超时时间

5.绑定socket

6.从Client端接收数据

7.发送数据到Client端

运行:结果:

1.串口调试找到wifi的IP地址(不太清楚是在哪里打印的,工程模版自带打印)

2.使用上述wifi 的IP地址,创建一个客户端(作为模拟客户端连接)

        这里发送数据有回应(正确)

四。WiFi TCP Client编程

1.功能分析

实验要求:

完成TCP Client功能开发

1.PC模拟TCP Server,指定(IP,PORT),等待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

(1)tcpclient.h

#ifndef __TCPCLIENT_H__
#define __TCPCLIENT_H__

#ifdef __cplusplus
extern "C" {
#endif

void ATaskTcpClient( void *pvParameters );
void TcpClient_init(void);

#ifdef __cplusplus
}
#endif

#endif

(2)tcpclient.c

注意:SERVERADDR为电脑的IP地址(无线网ipv4,ipconfig查找),因为电脑作为服务器,所以wifi板子需要对目标ip做出设定。

#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 "tcpclient.h"

#define SERVERADDR "192.168.3.12"
#define SERVERPORT 8000

/******************************************************************************
 * FunctionName : ATaskTcpClient
 * Description  : ATaskTcpClient 任务
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ATaskTcpClient( void *pvParameters )
{
    int iVariableExample = 0;
    int fd = -1;

    int NetTimeOnt = 5000;
    int ret;

    struct sockaddr_in ServerAddr;
    char Tcpmsg[48];

    STATION_STATUS StaStatus;
    do
    {
        StaStatus = wifi_station_get_connect_status();
        vTaskDelay(100);

    }while(StaStatus != STATION_GOT_IP);
   
    fd = socket(PF_INET,SOCK_STREAM,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);

    do
        {
            ret = connect(fd,(struct sockaddr*)&ServerAddr,ServerAddr.sin_len);
            if(ret != 0)
            {
                printf("connect is fail!\n");
                vTaskDelay(100);
            }
        }
    while (ret != 0);       
    for(;;)
    {
        send(fd,"I am TcpClient!",sizeof("I am TcpClient!"),0);
        do
         {
            ret = recv(fd,Tcpmsg,48,0);
            if(ret > 0)
            {
                printf("TcpServer:%s\n",Tcpmsg);
            }
            else
            {
                printf("TcpServer data is no!\n");
            }

         }while(ret == -1);     
    }
    vTaskDelete( NULL );

}

/******************************************************************************
 * FunctionName : TcpClient_init
 * Description  : TcpClient_init 初始化
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void TcpClient_init(void)
{
    xTaskCreate(ATaskTcpClient, "TcpClient", 256, NULL, 4, NULL);
}

user_main修改

TcpClient_init();

代码详细解释

1.判断是否获取到IP地址

2.创建socket

3.设置接收超时时间

4.赋值server信息

5.连接到server端

6.发送数据到server端

7.从server端接收数据

4.编译:

1.打开虚拟机,

2.进入共享文件夹

2.进入tcpclient工程文件

3.编译

(1)./gen_misc.sh 选y(回车)1(回车)2(回车)3

出现上述表示编译成功

5.运行。

运行成功

6.结果:

电脑(服务器端发送数据有回复)

五。实验:WiFi TCP Server编程

1.功能分析

实验要求:

完成TCP Server功能开发

1.PC模拟TCP Client,指定Server(IP,PORT)

    (1)进行连接,连接成功后发生“I am Client!”

    (2)Sever收到数据后,向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)tcpserver.h

#ifndef __TCPSERVER_H__
#define __TCPSERVER_H__

#ifdef __cplusplus
extern "C" {
#endif

void ATaskTcpServer( void *pvParameters );
void TcpServer_init(void);

#ifdef __cplusplus
}
#endif

#endif

    (2)tcpserver.c

#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 "tcpserver.h"

#define SERVERADDR "192.168.31.158"
#define SERVERPORT 8000
/******************************************************************************
 * FunctionName : ATaskTcpServer
 * Description  : ATaskTcpServer 任务
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ATaskTcpServer( void *pvParameters )
{
    int iVariableExample = 0;
    int fd = -1;
    int cfd = -1;
    int NetTimeOnt = 20000;
    int ret;

    struct sockaddr_in ServerAddr;
    struct sockaddr ClientAddr;
    socklen_t ClientAddrlen = sizeof(struct sockaddr);
    char Tcpmsg[48];

    STATION_STATUS StaStatus;
    do
    {
        StaStatus = wifi_station_get_connect_status();
        vTaskDelay(100);
    }while(StaStatus != STATION_GOT_IP);
    
    fd = socket(PF_INET,SOCK_STREAM,0);
    if(fd == -1)
    {
        printf("get socket fail!\n");
        vTaskDelete(NULL);
        return;

    }
    setsockopt(fd,SOL_SOCKET,SO_RCVTIMEO,&NetTimeOnt,sizeof(int));

    memset(&ServerAddr,0,sizeof(ServerAddr));
    ServerAddr.sin_family = AF_INET;
    ServerAddr.sin_addr.s_addr = INADDR_ANY;
    ServerAddr.sin_port = htons(SERVERPORT);
    ServerAddr.sin_len = sizeof(ServerAddr);

    if(bind(fd,(struct sockaddr*)&ServerAddr,ServerAddr.sin_len) != 0)
    {        
        printf("bind socket fail!\n");
        vTaskDelete(NULL);
        return;
    }

    if(listen(fd,5) != 0)
    {
        printf("listen socket fail!\n");
        vTaskDelete(NULL);
        return;
    }   
    for(;;)
    {
        cfd = accept(fd,&ClientAddr,&ClientAddrlen);
        if(cfd != -1)
        {
            ret = recv(cfd,Tcpmsg,48,0);
            if(ret > 0)
            {
                printf("TcpClient:%s\n",Tcpmsg);
                send(cfd,"I am TcpServer!",sizeof("I am TcpServer!"),0);
            }
            else
            {
                printf("TcpClient data is no!\n");
            }
        }
        close(cfd);
    }
    vTaskDelete( NULL );
}

/******************************************************************************
 * FunctionName : TcpServer_init
 * Description  : TcpServer_init 初始化
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void TcpServer_init(void)
{
    xTaskCreate(ATaskTcpServer, "TcpServer", 256, NULL, 4, NULL);
}

2.修改user_main.c

TcpServer_init();

代码详解

1.判断是否获取到IP地址

2.创建socket

3.设置接收超时时间

4.赋值server信息

5.绑定socket

6.监听socket

7.处理Client 连接

8.接收Client 数据

9.发送数据到Server

10.关闭socket

结果:

目标地址为wifi 的打印地址(这里只能出现一次相应的原因是:每次相应客户端时候,会连接中断,看这个客户端已经显示未连接)

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
高通WiFi开发手册是一本详细介绍高通公司WiFi芯片开发的指南。该手册提供了丰富的技术资料和开发指导,帮助开发者理解和应用高通WiFi芯片的功能和特性。 首先,该手册详细介绍了高通WiFi芯片的架构和性能特点。它解释了芯片支持的不同WiFi标准(如802.11ac和802.11ax)以及频段的覆盖范围。开发者可以通过阅读这些信息来了解芯片的硬件要求和适用场景,从而更好地设计和优化他们的应用。 其次,手册提供了编程接口和开发工具的使用指南。它详细介绍了高通WiFi芯片的驱动程序和API,包括连接管理、数据传输和安全性等。开发者可以通过这些接口来控制和操作芯片,实现各种功能,如WiFi连接的建立和维护,数据的传输和加密等。同时,手册还介绍了高通提供的开发工具,如调试器和模拟器,帮助开发者进行调试和性能优化。 最后,手册着重介绍了一些常见问题和解决方案。它列举了一些常见的WiFi连接问题和网络配置错误,并提供了解决这些问题的方法和建议。这对开发者来说非常有帮助,可以帮助他们更快地解决一些常见的技术难题,提高开发效率。 综上所述,高通WiFi开发手册是一本非常有价值的技术文档,对开发者来说是一个宝贵的参考资源。通过阅读和理解该手册,开发者可以更好地利用高通WiFi芯片的功能和特性,开发出高性能和可靠的WiFi应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值