大家好,我是你的好朋友思创斯。网站金沙1005首页:https://ispacesoft.com
参考网上连老师的tcp自己整理一套tcp服务端的开发,整体思路大概如下:
1、tcp服务首先需要连接wifi,采用的是sta模式,在编写tcp服务端代码之前已经对wifi功能进行了学习,代码也编写好了,所以直接封装一下拿来使用就ok!!代码如下,在applications/sample/wifi-iot/app/下新建wifi_demo文件夹,然后新建wifi_sta_connect.h文件和wifi_sta_connect.c文件:
wifi_sta_connect.h
#ifndef _wifi_sta_connect_h
#define _wifi_sta_connect_h
extern int g_connected;
//wifi sta模式相关功能函数
void printlinkedinfo(wifilinkedinfo* info);
void onwificonnectionchanged(int state, wifilinkedinfo* info);
void onwifiscanstatechanged(int state, int size);
#endif
wifi_sta_connect.c
#include
#include
#include
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "wifi_device.h"
#include "lwip/netifapi.h"
#include "lwip/api_shell.h"
#include "wifi_sta_connect.h"
void printlinkedinfo(wifilinkedinfo* info)
{
if (!info) return;
static char macaddress[32] = {
0};
unsigned char* mac = info->bssid;
snprintf(macaddress, sizeof(macaddress), "x:x:x:x:x:x",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
printf("bssid: %s, rssi: %d, connstate: %d, reason: %d, ssid: %s\r\n",
macaddress, info->rssi, info->connstate, info->disconnectedreason, info->ssid);
}
int g_connected = 0;
void onwificonnectionchanged(int state, wifilinkedinfo* info)
{
if (!info) return;
printf("%s %d, state = %d, info = \r\n", __function__, __line__, state);
printlinkedinfo(info);
if (state == wifi_state_avaliable) {
g_connected = 1;
} else {
g_connected = 0;
}
}
void onwifiscanstatechanged(int state, int size)
{
printf("%s %d, state = %x, size = %d\r\n", __function__, __line__, state, size);
}
2、wifi功能模块封装的相对简单,后期如果需要更多的功能,在模块中添加即可,接下来就是tcp服务端代码的编写,其中需要调用wifi功能。
在applications/sample/wifi-iot/app下新建socket_demo文件夹,然后添加tcp_server_test.c文件
tcp_server_test.c
#include
#include
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "wifi_device.h"
#include "lwip/api_shell.h"
#include "hi_wifi_api.h"
#include "lwip/ip_addr.h"
#include "lwip/netifapi.h"
#include "lwip/sockets.h"
#include "wifi_sta_connect.h"
#define server_port_tcp 6666
#define tcp_backlog 10
/* 在sock_fd 进行监听,在 new_fd 接收新的链接 */
int sock_fd, new_fd;
char recvbuf[512];
char *buf = "hello! i'm server!";
int tcp_server_demo(void){
/* 自己的地址信息 */
struct sockaddr_in my_addr;
/* 连接者的地址信息*/
struct sockaddr_in their_addr;
int sin_size;
struct sockaddr_in *cli_addr;
printf("%s %d \r\n", __file__, __line__);
/* 1 、创建socket */
if((sock_fd = socket(af_inet, sock_stream, 0)) == -1)
{
printf("%s %d \r\n", __file__, __line__);
perror("socket is error\r\n");
exit(1);
}
/* 主机字节顺序 */
/* 协议 */
my_addr.sin_family = af_inet;
my_addr.sin_port = htons(6666);//设置你的端口号
/* 当前ip 地址写入 */
my_addr.sin_addr.s_addr = inaddr_any;
/* 将结构体其余的都清零 */
bzero(&(my_addr.sin_zero), 8);
printf("%s %d \r\n", __file__, __line__);
/* bind 绑定*/
if(bind(sock_fd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
{
printf("%s %d \r\n", __file__, __line__);
perror("bind is error\r\n");
exit(1);
}
printf("%s %d \r\n", __file__, __line__);
/* 开始监听 */
if(listen(sock_fd, tcp_backlog) == -1)
{
perror("listen is error\r\n");
exit(1);
}
printf("%s %d \r\n", __file__, __line__);
printf("start accept\n");
/* accept() 循环 */
while(1)
{
sin_size = sizeof(struct sockaddr_in);
printf("%s %d \r\n", __file__, __line__);
if((new_fd = accept(sock_fd, (struct sockaddr *)&their_addr, (socklen_t *)&sin_size)) == -1)
{
perror("accept");
continue;
}
cli_addr = malloc(sizeof(struct sockaddr));
printf("accept addr\r\n");
if(cli_addr != null)
{
memcpy(cli_addr, &their_addr, sizeof(struct sockaddr));
}
//处理目标
ssize_t ret;
while(1)
{
printf("%s %d \r\n", __file__, __line__);
if((ret = recv(new_fd, recvbuf, sizeof(recvbuf), 0)) == -1){
printf("recv error \r\n");
return -1;
}
printf("recv :\r\n");
printf("%s", recvbuf);
printf("\r\n");
sleep(2);
if((ret = send(new_fd, buf, strlen(buf) 1, 0)) == -1)
{
perror("send : ");
}
sleep(2);
}
close(new_fd);
return 0;
}
}
void start_sta_mode(void){
wifierrorcode errcode;
wifievent eventlistener = {
.onwificonnectionchanged = onwificonnectionchanged, //连接状态改变
.onwifiscanstatechanged = onwifiscanstatechanged //扫描状态变化
};
wifideviceconfig apconfig = {
};
int netid = -1;
osdelay(10);
errcode = registerwifievent(&eventlistener); //注册wifi事件的回调函数
printf("registerwifievent: %d\r\n", errcode);
// setup your ap params
strcpy(apconfig.ssid, "*******"); //设置你的wifi名称
strcpy(apconfig.presharedkey, "*******"); //设置你的wifi密码
apconfig.securitytype = wifi_sec_type_psk;
while (1) {
errcode = enablewifi(); //打开wifi设备的sta模式,使其可以扫描
printf("enablewifi: %d\r\n", errcode);
osdelay(10);
errcode = adddeviceconfig(&apconfig, &netid); //增加wifi设备的配置,分配得到一个net id保存在netid中
printf("adddeviceconfig: %d\r\n", errcode);
g_connected = 0;
errcode = connectto(netid);
printf("connectto(%d): %d\r\n", netid, errcode);
while (!g_connected) {
osdelay(10);
}
printf("g_connected: %d\r\n", g_connected);
osdelay(50);
// 联网业务开始
struct netif* iface = netifapi_netif_find("wlan0");
if (iface) {
err_t ret = netifapi_dhcp_start(iface);
printf("netifapi_dhcp_start: %d\r\n", ret);
osdelay(200); // wait dhcp server give me ip
ret = netifapi_netif_common(iface, dhcp_clients_info_show, null);
printf("netifapi_netif_common: %d\r\n", ret);
}
// 模拟一段时间的联网业务
// int timeout = 60;
while (1) {
// osdelay(100);
// printf("after %d seconds, i'll disconnect wifi!\n", timeout);
printf("ongoing iot business\n");
uint32_t result = tcp_server_demo();
if (result==0)
{
/* code */
printf("i'll disconnect wifi!\n");
break;
}
}
// 联网业务结束
err_t ret = netifapi_dhcp_stop(iface);
printf("netifapi_dhcp_stop: %d\r\n", ret);
disconnect(); // disconnect with your ap
removedevice(netid); // remove ap config
errcode = disablewifi();
printf("disablewifi: %d\r\n", errcode);
osdelay(200);
}
}
void tcpservertask(void* arg){
(void) arg;
start_sta_mode();
// tcp_server_demo();
}
void tcpserverentry(void){
osthreadattr_t attr;
attr.name = "tcpservertask";
attr.attr_bits = 0u;
attr.cb_mem = null;
attr.cb_size = 0u;
attr.stack_mem = null;
attr.stack_size = 10240;
attr.priority = osprioritynormal;
if (osthreadnew(tcpservertask, null, &attr) == null) {
printf("[wificonnectdemo] falied to create tcpservertask!\n");
}
}
sys_run(tcpserverentry);
在applications/sample/wifi-iot/app下新建socket_demo文件夹,然后添加build.gn文件,这里需要把封装wifi功能模块的文件包含进去:
build.gn
static_library("socket_demo") {
sources = [
"tcp_server_test.c",
]
include_dirs = [
"//utils/native/lite/include",
"//kernel/liteos_m/components/cmsis/2.0",
"//base/iot_hardware/interfaces/kits/wifiiot_lite",
"//foundation/communication/interfaces/kits/wifi_lite/wifiservice",
"//vendor/hisi/hi3861/hi3861/third_party/lwip_sack/include/",
"//foundation/communication/wifi_lite/interfaces/wifiservice",
"//applications/sample/wifi-iot/app/wifi_demo",
]
}
3、最后修改applications/sample/wifi-iot/app/build.gn文件:
import("//build/lite/config/component/lite_component.gni")
lite_component("app") {
features = [
"wifi_demo",
"socket_demo",
]
}
4、最后编译烧录即可,自己可以编写一个tcp客户端去连接服务端进行测试,作为学习harmonyos的新手,还有许多不足,欢迎大家留言补充,共同学习成长!
文章由思创斯整理,转载请注明出处:https://ispacesoft.com/4661.html