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、拓扑结构
2.2、基本流程原理:
3、实验效果
服务端监听连接,等待设备端连接后进行交互,服务端和设备端相互发送数据并接受数据
3.1、服务端
3.2、设备端
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开发板上找到属于你的快乐。
如需更多技术支持,可加入钉钉开发者群,或者关注微信公众号
更多技术与解决方案介绍,请访问阿里云AIoT首页https://iot.aliyun.com/
转载:https://blog.csdn.net/HaaSTech/article/details/112380340