文章目录
- OH系统版本:OpenHarmony3.1Release IDE: 3.0.0.900 实现语言:JS
-
- 参考地址:Socket连接 TCP通信流程: Initial TCP ————> Bind IP ————> Connect Target IP ————> Send/Receive 初始化IP相关配置: - 引用模块: import socket from '@ohos.net.socket'- 添加权限:ohos.permission.INTERNET、ohos.permission.GET_WIFI_INFO- 创建对象:let tcp = socket.constructTCPSocketInstance(); 绑定IP与端口号 bind(address: NetAddress, callback: AsyncCallback<void>): void绑定IP地址和端口,端口可以指定或由系统随机分配。使用callback方法作为异步方法。需要权限:ohos.permission.INTERNET系统能力:SystemCapability.Communication.NetStack示例:let tcp = socket.constructTCPSocketInstance();tcp.bind({address: '192.168.xx.xxx', port: xxxx, family: 1}, err => { if (err) { console.log('bind fail'); return; } console.log('bind success');}) 连接目标IP connect(options: TCPConnectOptions, callback: AsyncCallback<void>): void连接到指定的IP地址和端口。使用callback方法作为异步方法。需要权限:ohos.permission.INTERNET系统能力:SystemCapability.Communication.NetStack示例:let tcp = socket.constructTCPSocketInstance();tcp.connect({ address: {address: '192.168.xx.xxx', port: xxxx, family: 1} , timeout: 6000}, err => { if (err) { console.log('connect fail'); return; } console.log('connect success');}) 发送/接收数据 //发送数据 send(options: TCPSendOptions, callback: AsyncCallback<void>): void通过TCPSocket连接发送数据。使用callback方式作为异步方法。说明: connect方法调用成功后,才可调用此方法。需要权限:ohos.permission.INTERNET系统能力:SystemCapability.Communication.NetStack示例: tcpSend() { tcp.send({ data: this.app_msg, }, err => { if (err) { console.log('send fail'); return; } }); },//接收数据 并解析数据为Stringon(type: ‘message’, callback: Callback<{message: ArrayBuffer, remoteInfo: SocketRemoteInfo}>): void订阅TCPSocket连接的接收消息事件。使用callback方式作为异步方法。系统能力:SystemCapability.Communication.NetStacktcp.on('message', value => { console.log("on message") let buffer = value.message let dataView = new DataView(buffer) let str = "" for (let i = 0;i < dataView.byteLength; ++i) { str += String.fromCharCode(dataView.getUint8(i)) } console.log("on connect received:" + str) this.receive_data=str; prompt.showToast({ message:str, duration:1000 }); });
- 按照上一节的流程,编写对应的JS程序即可。UI如下: 第一个按钮用于绑定IP,并设置订阅TCPSocket相关的订阅事件。 tcpClient() { // 订阅TCPSocket相关的订阅事件 tcp.on('message', value => { console.log("on message") let buffer = value.message let dataView = new DataView(buffer) let str = "" for (let i = 0;i < dataView.byteLength; ++i) { str += String.fromCharCode(dataView.getUint8(i)) } console.log("on connect received:" + str) this.receive_data=str; prompt.showToast({ message:str, duration:1000 }); }); tcp.on('connect', () => { console.log("on connect") }); tcp.on('close', () => { console.log("on close") }); // 绑定IP地址和端口。 let bindAddress = { address: wifi.getIpInfo().ipAddress, port: 1234, family: 1 }; tcp.bind(bindAddress, err => { if (err) { console.log('bind fail'); return; } console.log('bind success'); prompt.showToast({ message:"bind success", }) }); }, 第二个按钮用于连接Hi3861: tcpConnect() { prompt.showToast({ message:'wifiAddr'+wifi.isConnected()+wifi.getIpInfo().ipAddress, });// let promise = tcp.connect({ address: {address:'192.168.137.92', port: 8888, family: 1} , timeout: 6000});// promise.then(() => {// console.log('connect success')// prompt.showToast({// message:"connect success",// });// }).catch(err => {// prompt.showToast({// message:"connect fail",// });// console.log('connect fail');// }); tcp.connect({ address: {address: '192.168.137.92', port: 8888, family: 1} , timeout: 6000}, err => { if (err) { console.log('connect fail'); prompt.showToast({ message:"connect fail", }); return; } console.log('connect success'); prompt.showToast({ message:"connect success", }); }) }, 第三个按钮实现发送数据: tcpSend() { tcp.send({ data: this.app_msg, }, err => { if (err) { console.log('send fail'); prompt.showToast({ message:"send fail", }); return; } prompt.showToast({ message:"send successful" }) }); },
-
- 参考小熊派开发板TCP server案例。主要任务是开启wifi,获取周围wifi列表。 #define SELECT_WLAN_PORT "wlan0"int WifiConnect(const char *ssid, const char *psk){ WifiScanInfo *info = NULL; unsigned int size = WIFI_SCAN_HOTSPOT_LIMIT; static struct netif *g_lwip_netif = NULL; osDelay(200); printf("<--System Init-->\r\n"); //初始化WIFI WiFiInit(); //使能WIFI if (EnableWifi() != WIFI_SUCCESS) { printf("EnableWifi failed, error = %d\r\n", error); return -1; } //判断WIFI是否激活 if (IsWifiActive() == 0) { printf("Wifi station is not actived.\r\n"); return -1; } //分配空间,保存WiFi信息 info = malloc(sizeof(WifiScanInfo) * WIFI_SCAN_HOTSPOT_LIMIT); if (info == NULL) { return -1; } //轮询查找WiFi列表 do{ //重置标志位 ssid_count = 0; g_staScanSuccess = 0; //开始扫描 Scan(); //等待扫描结果 WaitSacnResult(); //获取扫描列表 error = GetScanInfoList(info, &size); }while(g_staScanSuccess != 1); //连接指定的WiFi热点 for(uint8_t i = 0; i < ssid_count; i++) { if (strcmp(ssid, info[i].ssid) == 0) { int result; printf("Select:%3d wireless, Waiting...\r\n", i+1); //拷贝要连接的热点信息 WifiDeviceConfig select_ap_config = {0}; strcpy(select_ap_config.ssid, info[i].ssid); strcpy(select_ap_config.preSharedKey, psk); select_ap_config.securityType = SELECT_WIFI_SECURITYTYPE; if (AddDeviceConfig(&select_ap_config, &result) == WIFI_SUCCESS) { if (ConnectTo(result) == WIFI_SUCCESS && WaitConnectResult() == 1) { printf("WiFi connect succeed!\r\n"); g_lwip_netif = netifapi_netif_find(SELECT_WLAN_PORT); break; } } } if(i == ssid_count-1) { printf("ERROR: No wifi as expected\r\n"); while(1) osDelay(100); } } //启动DHCP if (g_lwip_netif) { dhcp_start(g_lwip_netif); printf("begain to dhcp\r\n"); } //等待DHCP for(;;) { if(dhcp_is_bound(g_lwip_netif) == ERR_OK) { printf("<-- DHCP state:OK -->\r\n"); //打印获取到的IP信息 netifapi_netif_common(g_lwip_netif, dhcp_clients_info_show, NULL); break; } printf("<-- DHCP state:Inprogress -->\r\n"); osDelay(100); } osDelay(100); return 0;}
- 连接指定wifi,创建socket server,监听指定IP 端口。 char *buf = "Hello! I'm BearPi-HM_Nano TCP Server!";static void TCPServerTask(void){ //服务端地址信息 struct sockaddr_in server_sock; //客户端地址信息 struct sockaddr_in client_sock; int sin_size; struct sockaddr_in *cli_addr; //连接Wifi WifiConnect("r1", "88888889"); //创建socket if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket is error\r\n"); exit(1); } bzero(&server_sock, sizeof(server_sock)); server_sock.sin_family = AF_INET; server_sock.sin_addr.s_addr = htonl(INADDR_ANY); server_sock.sin_port = htons(_PROT_); //调用bind函数绑定socket和地址 if (bind(sock_fd, (struct sockaddr *)&server_sock, sizeof(struct sockaddr)) == -1) { perror("bind is error\r\n"); exit(1); } //调用listen函数监听(指定port监听) if (listen(sock_fd, TCP_BACKLOG) == -1) { perror("listen is error\r\n"); exit(1); } printf("start accept\n"); //调用accept函数从队列中 while (1) { sin_size = sizeof(struct sockaddr_in); if ((new_fd = accept(sock_fd, (struct sockaddr *)&client_sock, (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, &client_sock, sizeof(struct sockaddr)); } //处理目标 ssize_t ret; while (1) { if ((ret = recv(new_fd, recvbuf, sizeof(recvbuf), 0)) == -1) { printf("recv error \r\n"); } printf("recv :%s\r\n", recvbuf); sleep(2); if ((ret = send(new_fd, buf, strlen(buf) + 1, 0)) == -1) { perror("send : "); } sleep(2); } close(new_fd); }}
- 将Hi3861、Dayu200都连接到同一个wifi下,事先匹配好IP地址和端口: 连接后Hi3861只要接收到数据就会返回一段字符串,Hi3861接收到的数据可以使用串口查看: 想了解更多关于开源的内容,请访问: 51CTO 开源基础软件社区 https://ost.51cto.com

- OH系统版本:OpenHarmony3.1Release
- IDE: 3.0.0.900
- 实现语言:JS
参考地址:Socket连接
TCP通信流程:
Initial TCP ————> Bind IP ————> Connect Target IP ————> Send/Receive
- 初始化IP相关配置:
- 引用模块: import socket from '@ohos.net.socket'
- 添加权限:ohos.permission.INTERNET、ohos.permission.GET_WIFI_INFO
- 创建对象:let tcp = socket.constructTCPSocketInstance();
- 绑定IP与端口号
bind(address: NetAddress, callback: AsyncCallback<void>): void
绑定IP地址和端口,端口可以指定或由系统随机分配。使用callback方法作为异步方法。
需要权限:ohos.permission.INTERNET
系统能力:SystemCapability.Communication.NetStack
示例:
let tcp = socket.constructTCPSocketInstance();
tcp.bind({address: '192.168.xx.xxx', port: xxxx, family: 1}, err => {
if (err) {
console.log('bind fail');
return;
}
console.log('bind success');
})
- 连接目标IP
connect(options: TCPConnectOptions, callback: AsyncCallback<void>): void
连接到指定的IP地址和端口。使用callback方法作为异步方法。
需要权限:ohos.permission.INTERNET
系统能力:SystemCapability.Communication.NetStack
示例:
let tcp = socket.constructTCPSocketInstance();
tcp.connect({ address: {address: '192.168.xx.xxx', port: xxxx, family: 1} , timeout: 6000}, err => {
if (err) {
console.log('connect fail');
return;
}
console.log('connect success');
})
- 发送/接收数据
//发送数据
send(options: TCPSendOptions, callback: AsyncCallback<void>): void
通过TCPSocket连接发送数据。使用callback方式作为异步方法。
说明: connect方法调用成功后,才可调用此方法。
需要权限:ohos.permission.INTERNET
系统能力:SystemCapability.Communication.NetStack
示例:
tcpSend()
{
tcp.send({
data: this.app_msg,
}, err => {
if (err) {
console.log('send fail');
return;
}
});
},
//接收数据 并解析数据为String
on(type: ‘message’, callback: Callback<{message: ArrayBuffer, remoteInfo: SocketRemoteInfo}>): void
订阅TCPSocket连接的接收消息事件。使用callback方式作为异步方法。
系统能力:SystemCapability.Communication.NetStack
tcp.on('message', value => {
console.log("on message")
let buffer = value.message
let dataView = new DataView(buffer)
let str = ""
for (let i = 0;i < dataView.byteLength; ++i) {
str += String.fromCharCode(dataView.getUint8(i))
}
console.log("on connect received:" + str)
this.receive_data=str;
prompt.showToast({
message:str,
duration:1000
});
});
按照上一节的流程,编写对应的JS程序即可。UI如下:

第一个按钮用于绑定IP,并设置订阅TCPSocket相关的订阅事件。
tcpClient()
{
// 订阅TCPSocket相关的订阅事件
tcp.on('message', value => {
console.log("on message")
let buffer = value.message
let dataView = new DataView(buffer)
let str = ""
for (let i = 0;i < dataView.byteLength; ++i) {
str += String.fromCharCode(dataView.getUint8(i))
}
console.log("on connect received:" + str)
this.receive_data=str;
prompt.showToast({
message:str,
duration:1000
});
});
tcp.on('connect', () => {
console.log("on connect")
});
tcp.on('close', () => {
console.log("on close")
});
// 绑定IP地址和端口。
let bindAddress = {
address: wifi.getIpInfo().ipAddress,
port: 1234,
family: 1
};
tcp.bind(bindAddress, err => {
if (err) {
console.log('bind fail');
return;
}
console.log('bind success');
prompt.showToast({
message:"bind success",
})
});
},
第二个按钮用于连接Hi3861:
tcpConnect()
{
prompt.showToast({
message:'wifiAddr'+wifi.isConnected()+wifi.getIpInfo().ipAddress,
});
// let promise = tcp.connect({ address: {address:'192.168.137.92', port: 8888, family: 1} , timeout: 6000});
// promise.then(() => {
// console.log('connect success')
// prompt.showToast({
// message:"connect success",
// });
// }).catch(err => {
// prompt.showToast({
// message:"connect fail",
// });
// console.log('connect fail');
// });
tcp.connect({ address: {address: '192.168.137.92', port: 8888, family: 1} , timeout: 6000}, err => {
if (err) {
console.log('connect fail');
prompt.showToast({
message:"connect fail",
});
return;
}
console.log('connect success');
prompt.showToast({
message:"connect success",
});
})
},
第三个按钮实现发送数据:
tcpSend()
{
tcp.send({
data: this.app_msg,
}, err => {
if (err) {
console.log('send fail');
prompt.showToast({
message:"send fail",
});
return;
}
prompt.showToast({
message:"send successful"
})
});
},
参考小熊派开发板TCP server案例。主要任务是开启wifi,获取周围wifi列表。
#define SELECT_WLAN_PORT "wlan0"
int WifiConnect(const char *ssid, const char *psk)
{
WifiScanInfo *info = NULL;
unsigned int size = WIFI_SCAN_HOTSPOT_LIMIT;
static struct netif *g_lwip_netif = NULL;
osDelay(200);
printf("<--System Init-->\r\n");
//初始化WIFI
WiFiInit();
//使能WIFI
if (EnableWifi() != WIFI_SUCCESS)
{
printf("EnableWifi failed, error = %d\r\n", error);
return -1;
}
//判断WIFI是否激活
if (IsWifiActive() == 0)
{
printf("Wifi station is not actived.\r\n");
return -1;
}
//分配空间,保存WiFi信息
info = malloc(sizeof(WifiScanInfo) * WIFI_SCAN_HOTSPOT_LIMIT);
if (info == NULL)
{
return -1;
}
//轮询查找WiFi列表
do{
//重置标志位
ssid_count = 0;
g_staScanSuccess = 0;
//开始扫描
Scan();
//等待扫描结果
WaitSacnResult();
//获取扫描列表
error = GetScanInfoList(info, &size);
}while(g_staScanSuccess != 1);
//连接指定的WiFi热点
for(uint8_t i = 0; i < ssid_count; i++)
{
if (strcmp(ssid, info[i].ssid) == 0)
{
int result;
printf("Select:%3d wireless, Waiting...\r\n", i+1);
//拷贝要连接的热点信息
WifiDeviceConfig select_ap_config = {0};
strcpy(select_ap_config.ssid, info[i].ssid);
strcpy(select_ap_config.preSharedKey, psk);
select_ap_config.securityType = SELECT_WIFI_SECURITYTYPE;
if (AddDeviceConfig(&select_ap_config, &result) == WIFI_SUCCESS)
{
if (ConnectTo(result) == WIFI_SUCCESS && WaitConnectResult() == 1)
{
printf("WiFi connect succeed!\r\n");
g_lwip_netif = netifapi_netif_find(SELECT_WLAN_PORT);
break;
}
}
}
if(i == ssid_count-1)
{
printf("ERROR: No wifi as expected\r\n");
while(1) osDelay(100);
}
}
//启动DHCP
if (g_lwip_netif)
{
dhcp_start(g_lwip_netif);
printf("begain to dhcp\r\n");
}
//等待DHCP
for(;;)
{
if(dhcp_is_bound(g_lwip_netif) == ERR_OK)
{
printf("<-- DHCP state:OK -->\r\n");
//打印获取到的IP信息
netifapi_netif_common(g_lwip_netif, dhcp_clients_info_show, NULL);
break;
}
printf("<-- DHCP state:Inprogress -->\r\n");
osDelay(100);
}
osDelay(100);
return 0;
}
连接指定wifi,创建socket server,监听指定IP 端口。
char *buf = "Hello! I'm BearPi-HM_Nano TCP Server!";
static void TCPServerTask(void)
{
//服务端地址信息
struct sockaddr_in server_sock;
//客户端地址信息
struct sockaddr_in client_sock;
int sin_size;
struct sockaddr_in *cli_addr;
//连接Wifi
WifiConnect("r1", "88888889");
//创建socket
if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket is error\r\n");
exit(1);
}
bzero(&server_sock, sizeof(server_sock));
server_sock.sin_family = AF_INET;
server_sock.sin_addr.s_addr = htonl(INADDR_ANY);
server_sock.sin_port = htons(_PROT_);
//调用bind函数绑定socket和地址
if (bind(sock_fd, (struct sockaddr *)&server_sock, sizeof(struct sockaddr)) == -1)
{
perror("bind is error\r\n");
exit(1);
}
//调用listen函数监听(指定port监听)
if (listen(sock_fd, TCP_BACKLOG) == -1)
{
perror("listen is error\r\n");
exit(1);
}
printf("start accept\n");
//调用accept函数从队列中
while (1)
{
sin_size = sizeof(struct sockaddr_in);
if ((new_fd = accept(sock_fd, (struct sockaddr *)&client_sock, (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, &client_sock, sizeof(struct sockaddr));
}
//处理目标
ssize_t ret;
while (1)
{
if ((ret = recv(new_fd, recvbuf, sizeof(recvbuf), 0)) == -1)
{
printf("recv error \r\n");
}
printf("recv :%s\r\n", recvbuf);
sleep(2);
if ((ret = send(new_fd, buf, strlen(buf) + 1, 0)) == -1)
{
perror("send : ");
}
sleep(2);
}
close(new_fd);
}
}
将Hi3861、Dayu200都连接到同一个wifi下,事先匹配好IP地址和端口:

连接后Hi3861只要接收到数据就会返回一段字符串,Hi3861接收到的数据可以使用串口查看:

© 版权声明
文章版权归作者所有,未经允许请勿转载。