HaaS100开发板局域网基本网络通信

1、概要

本文的目标:

1、在AliOS Things上如何连到指定wifi上

2、在AliOS Things上如何通过socket和连接在相同网络的pc机进行通信

通过这个实验,作为一个入门,能够使用aos以及HaaS开发板快速连接wifi并且和局域网进行通信,为进一步开发更多的网络相关应用打下基础。

本实验基于TCP实验,以PC机作为server,HaaS100开发板作为client,进行数据通信。

本文读者对象:

1、初次接触HaaS100开发板的开发者

2、需要联网的开发者

3、需要进行局域网通信的开发者

2、拓扑结构和基本流程原理

2.1、拓扑结构

image.png

2.2、基本流程原理:

image.png

3、实验效果

服务端监听连接,等待设备端连接后进行交互,服务端和设备端相互发送数据并接受数据

3.1、服务端

image.png

3.2、设备端

image.png

4、实验准备

该实验所有代码参见github链接:

https://github.com/alibaba/AliOS-Things/tree/dev_3.1.0_haas/application/example/tcp_demo

4.1、服务端

服务端的代码按基本流程是创建一个socket进行监听,然后等待client连接后进行用户输入交互。

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/socket.h>


extern void communication(int fd);

int main()
{
    int serverfd, clientfd, len;
    struct sockaddr_in servaddr, clientaddr;
    memset(&servaddr, 0, sizeof(servaddr));
    memset(&clientaddr, 0, sizeof(clientaddr));

    serverfd = socket(AF_INET, SOCK_STREAM, 0);
    if (serverfd == -1) {
        printf("socket called failed!\n");
        exit(0);
    }
    else {
        printf("socket successfully created..\n");
    }

    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(8080);

    //绑定server ip地址
    if ((bind(serverfd, (struct sockaddr *)&servaddr, sizeof(servaddr))) != 0) {
        printf("socket bind failed...\n");
        exit(0);
    }
    else {
        printf("Socket successfully binded..\n");
    }

    if ((listen(serverfd, 5)) != 0) {
        printf("Listen failed...\n");
        exit(0);
    }
    else
        printf("Server listening..\n");
    len = sizeof(clientaddr);

    //等待设备连接
    clientfd = accept(serverfd, (struct sockaddr *)&clientaddr, &len);
    if (clientfd < 0) {
        printf("acccept failed!\n");
        exit(0);
    }
    else
        printf("server acccept the client...\n");

    //主循环交流
    communication(clientfd);
    close(serverfd);
}

#define MAX_INPUT_CHAR 100
void communication(int fd)
{
    int index;
    char input[MAX_INPUT_CHAR];

    while (1) {
        memset(input, 0, MAX_INPUT_CHAR);
        index = 0;

        //等待client发送消息
        read(fd, input, sizeof(input));
        printf("Receive from client: %s\n", input);
        printf("Pluse input sending to client : ");
        memset(input, 0, MAX_INPUT_CHAR);
        while ((input[index++] = getchar()) != '\n')
            ;

        //将input发送给client
        write(fd, input, sizeof(input));

        if (strncmp("exit", input, 4) == 0) {
            printf("Exit communication\n");
            break;
        }
    }
}

编译命令:

gcc server.c -o s.o

执行命令:

./s.o

4.2、设备端

设备端作为client,主要流程是注册基本命令后进行连接服务端,并且介绍到服务端消息后回应receive报文。

设备端代码分为两个部分,一个是wifi连接初始化部分,一个是进行tcp模拟的部分。

wifi连接初始化代码:

extern void handle_networktestcmd(char *pwbuf, int blen, int argc, char **argv);

static struct cli_command networktestcmds[] = {
    {
        .name = "network",
        .help = "netowork { tcp_c|tcp_s remote_ip remote_port data [times] } | { domain domain_info [ remote_port ]}",
        .function = handle_networktestcmd
    }
};

int application_start(int argc, char *argv[])
{
    printf("%s-%d called\n", __FUNCTION__, __LINE__);
    wifi_service_init();
    wifi_service_wifi_connect("ssid", "passwd", NULL, 10 * 1000);
    aos_cli_register_commands((const struct cli_command *)&networktestcmds[0], sizeof(networktestcmds) / sizeof(networktestcmds[0]));
}


void handle_networktestcmd(char *pwbuf, int blen, int argc, char **argv)
{
    char *ptype = NULL;
    int  ret = 0;

    aos_cli_init();


    printf("tcp demo entry here!\r\n");

    if (argc < 2 || NULL == argv){
        printf("invalid input netword test command argc %d argv %p \r\n", argc, argv);
        return;
    }

    ptype = argv[1];

    if (strcmp(ptype, "tcp_c") == 0) {
        ret = networktestcmd_tcp_client(argc, argv);
        if (ret){
            printf("fail to execute tcp client test command \r\n");
            return;
        }
    } else if (strcmp(ptype, "tcp_s") == 0) {
        ret = networktestcmd_tcp_server(argc, argv);
        if (ret){
            printf("fail to execute udp server test command \r\n");
            return;
        }
    }else {
        printf("invalid netword test command input \r\n");
    }
    printf("network command test successed \r\n");
    
}

tcp部分代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <aos/kernel.h>
#include "aos/init.h"
#include "board.h"
#include <k_api.h>
#include "aos/kernel.h"
#include <network/network.h>
#include <netmgr.h>
#include "aos/cli.h"


#define BUFFER_MAX_SIZE  1512
#define TCP_DEMO_TARGET_TCP_PORT 443

#ifndef IPADDR_NONE
#define IPADDR_NONE ((uint32_t)0xffffffffUL)
#endif
int networktestcmd_tcp_client(int argc, char **argv)
{
    int  ret = 0;
    int  readlen = 0;
    int  fd = 0;
    int  time = 0;
    int  testtimes = 10;
    char *pbuf = NULL;
    char *pcipaddr = NULL;
    char *pcdestport = NULL;
    char *pcdata = NULL;
    char *pctesttime = NULL;
    struct sockaddr_in addr;
    struct timeval timeout;
    
    if (argc < 5){
        printf("invalid input tcp clinet test command \r\n");
        return -1;
    }

    pcipaddr = argv[2];
    pcdestport = argv[3];
    pcdata = argv[4];
    
    if (argc == 6){
        pctesttime = argv[5];
        testtimes = atoi(pctesttime);
        if (0 == testtimes){
            printf("invalid input tcp client test time %s \r\n", pctesttime);
            return -1;
        }
    }

    memset(&addr, 0, sizeof(addr));
    addr.sin_port = htons((short)atoi(pcdestport));

    if (0 == addr.sin_port){
        printf("invalid input port info %s \r\n", pcdestport);
        return -1;
    }
    
    addr.sin_addr.s_addr = inet_addr(pcipaddr);

    if (IPADDR_NONE == addr.sin_addr.s_addr){
        printf("invalid input addr info %s \r\n", pcipaddr);
        return -1;
    }

    addr.sin_family = AF_INET;

    fd = socket(AF_INET,SOCK_STREAM,0);
    if (fd < 0){
        printf("fail to creat socket errno = %d \r\n", errno);
        return -1;
    }
    printf("client fd=%d, ip=%s, port=%d\n", fd, pcipaddr, addr.sin_port);
    timeout.tv_sec = 15;
    timeout.tv_usec = 0;

    if (setsockopt (fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,
                    sizeof(timeout)) < 0) {
        printf("setsockopt failed, errno: %d\r\n", errno);
        goto err;
    }
    
    if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) != 0) {
        printf("Connect failed, errno = %d, ip %s port %s \r\n", errno, pcipaddr, pcdestport);
        goto err;
    }
    
    pbuf = aos_malloc(BUFFER_MAX_SIZE);
    if (NULL == pbuf){
        printf("fail to malloc memory %d at %s %d \r\n", BUFFER_MAX_SIZE, __FUNCTION__, __LINE__);
        goto err;
    }
    
    while(1){
        // send-recv
        printf("send data to server: \"%s\"\r\n", pcdata);
        if ((ret = send(fd, pcdata, strlen(pcdata), 0)) <= 0) {
            printf("send data failed, errno = %d. for the %d time \r\n", errno, time);
            goto err;
        }
        
        memset(pbuf, 0, BUFFER_MAX_SIZE);
        
        printf("read data from server...\r\n");

        readlen = read(fd, pbuf, BUFFER_MAX_SIZE - 1);
        if (readlen < 0){
            printf("recv failed, errno = %d.\r\n", errno);
            goto err;
        }

        if (readlen == 0){
            printf("recv buf len is %d \r\n", readlen);
            break;
        }
        
        printf("recv server %d time reply len %d. str: %s\r\n", time, readlen, pbuf);
        
        time++;
        
        if (time >= testtimes){
            break;
        }
    }
    close(fd);
    aos_free(pbuf);
    return 0;
err:
    close(fd);
    if (NULL != pbuf){
        aos_free(pbuf);
    }
    return -1;
}

编译方式:

aos make tcp_demo@haas100 -c config
aos make

烧录镜像:

参见:https://help.aliyun.com/document_detail/184184.html?spm=a2c4g.11186623.6.640.2fc57c26X2xKr3

执行命令:

network tcp_c 192.168.8.116 8080 received

5、后记

本实验作为一个入门,能够使用AliOS Things以及HaaS开发板板快速连接wifi并且和局域网进行通信,为进一步开发更多的网络相关应用打下基础。后续基于HaaS开发板的TCP server、TCP client、UDP server、UDP client都是类似的做法。希望在HaaS开发板上找到属于你的快乐。

如需更多技术支持,可加入钉钉开发者群

image

更多技术与解决方案介绍,请访问阿里云AIoT首页https://iot.aliyun.com/

猜你喜欢

转载自blog.csdn.net/HaaSTech/article/details/112380340