前言
DevEco Studio版本:4.0.0.600
参考链接:OpenHarmony Socket
效果
TCPSocket
1、bind绑定本地IP地址
private bindTcpSocket() {
let localAddress = resolveIP(wifi.getIpInfo().ipAddress)
console.info("111111111 localAddress: " + localAddress);
//bind本地地址
tcpSocket.bind({ address: localAddress })
.then(() => {
console.info("111111111 绑定Tcp成功");
})
.catch(err => {
console.info("111111111 绑定Tcp失败,原因: " + err);
});
}
2、设置tcpSocket的监听
private tcpSocketListener() {
tcpSocket.on('connect', () => {
this.connectMessage = '已连接'
console.info("111111111 监听: 连接成功");
});
tcpSocket.on('message', (value: {
message: ArrayBuffer,
remoteInfo: socket.SocketRemoteInfo
}) => {
this.messageReceive = this.messageReceive + this.resolveArrayBuffer(value.message) + "\n"
console.info("111111111 接收服务器的数据: " + this.messageReceive);
});
tcpSocket.on('close', () => {
this.connectMessage = '未连接'
console.info("111111111 监听:关闭连接")
});
}
3、连接服务器
private tcpSocketConnect() {
//开始连接
tcpSocket.connect({
address: { address: connectAddress.address, port: connectAddress.port, family: connectAddress.family },
timeout: 6000
}).then(() => {
console.info("111111111 tcpSocketConnect:连接成功");
let tcpExtraOptions: socket.TCPExtraOptions = {
keepAlive: true, //是否保持连接。默认为false
OOBInline: true, //是否为OOB内联。默认为false
TCPNoDelay: true, //TCPSocket连接是否无时延。默认为false
socketLinger: {
on: true,
linger: 10
}, //socket是否继续逗留。- on:是否逗留(true:逗留;false:不逗留)。- linger:逗留时长,单位毫秒(ms),取值范围为0~65535。当入参on设置为true时,才需要设置。
receiveBufferSize: 1000, //接收缓冲区大小(单位:Byte),默认为0
sendBufferSize: 1000, //发送缓冲区大小(单位:Byte),默认为0。
reuseAddress: true, //是否重用地址。默认为false。
socketTimeout: 3000//套接字超时时间,单位毫秒(ms),默认为0。
}
tcpSocket.setExtraOptions(tcpExtraOptions, (err: BusinessError) => {
if (err) {
console.log('111111111 setExtraOptions 失败');
return;
}
console.log('111111111 setExtraOptions 成功');
});
}).catch((error) => {
console.info("111111111 tcpSocketConnect 连接失败,原因: " + JSON.stringify(error));
})
}
4、发送数据内容
private sendMessage() {
tcpSocket.getState().then((data) => {
console.info("111111111 连接状态: " + JSON.stringify(data))
//已连接
if (data.isConnected) {
//发送消息
tcpSocket.send({ data: `${this.inputContent}\n`, encoding: 'UTF-8' })
.then(() => {
this.messageReceive = this.messageReceive + "发送:" + this.inputContent + "\n"
console.info("111111111 消息发送成功");
})
.catch((error) => {
console.info("111111111 消息发送失败,原因:" + JSON.stringify(error));
})
} else {
console.info("111111111 没有连接");
this.connectMessage = '未连接,服务器断了'
}
})
}
5、结束释放资源
private tcpSocketRelease() {
tcpSocket.off("message")
tcpSocket.off("connect")
tcpSocket.off("close")
tcpSocket.close()
tcpSocket = null
}
6、UI实现
build() {
Column() {
TextInput({ placeholder: '请输入用户名', text: '测试数据:Test' })
.width('100%')
.margin({ top: 20, bottom: 20 })
.onChange((value: string) => {
this.inputContent = value
})
Button('发送数据')
.width('100%')
.margin({ top: 20, bottom: 20 })
.onClick(() => {
this.sendMessage()
})
Text() {
Span('连接状态:')
Span(this.connectMessage).fontColor(Color.Red)
}
Scroll() {
Column() {
Text() {
Span('内容:\n')
Span(this.messageReceive).fontColor(Color.Pink)
}
}.width('100%')
.alignItems(HorizontalAlign.Start)
}
.width("100%")
.alignSelf(ItemAlign.Start)
.flexShrink(1)
.margin({ top: 15 })
}
.alignItems(HorizontalAlign.Start)
.padding({ left: 15, right: 15 })
.width('100%')
.height('100%')
}
详细代码
1、Index.ets
import socket from '@ohos.net.socket';
import wifi from '@ohos.wifi';
import { BusinessError } from '@ohos.base';
import { resolveIP } from '../utils/IpUtil';
import util from '@ohos.util';
//tcp连接对象
let tcpSocket = socket.constructTCPSocketInstance();
//连接服务器的地址和端口
let connectAddress = {
address: '10.65.XX.XX', //要通信的 PC地址,CMD--->ipconfig查看
family: 1,
port: 6666
}
@Entry
@Component
struct Index {
@State connectMessage: string = '未连接'
@State messageReceive: string = ''
@State inputContent: string = ''
aboutToAppear() {
this.tcpSocketListener()
this.bindTcpSocket()
}
onPageShow() {
this.tcpSocketConnect()
}
onPageHide() {
this.tcpSocketRelease()
}
build() {
Column() {
TextInput({ placeholder: '请输入用户名', text: '测试数据:Test' })
.width('100%')
.margin({ top: 20, bottom: 20 })
.onChange((value: string) => {
this.inputContent = value
})
Button('发送数据')
.width('100%')
.margin({ top: 20, bottom: 20 })
.onClick(() => {
this.sendMessage()
})
Text() {
Span('连接状态:')
Span(this.connectMessage).fontColor(Color.Red)
}
Scroll() {
Column() {
Text() {
Span('内容:\n')
Span(this.messageReceive).fontColor(Color.Pink)
}
}.width('100%')
.alignItems(HorizontalAlign.Start)
}
.width("100%")
.alignSelf(ItemAlign.Start)
.flexShrink(1)
.margin({ top: 15 })
}
.alignItems(HorizontalAlign.Start)
.padding({ left: 15, right: 15 })
.width('100%')
.height('100%')
}
/**
* tcp连接状态和消息监听
*/
private tcpSocketListener() {
tcpSocket.on('connect', () => {
this.connectMessage = '已连接'
console.info("111111111 监听: 连接成功");
});
tcpSocket.on('message', (value: {
message: ArrayBuffer,
remoteInfo: socket.SocketRemoteInfo
}) => {
this.messageReceive = this.messageReceive + this.resolveArrayBuffer(value.message) + "\n"
console.info("111111111 接收服务器的数据: " + this.messageReceive);
});
tcpSocket.on('close', () => {
this.connectMessage = '未连接'
console.info("111111111 监听:关闭连接")
});
}
/**
* 绑定Tcp本地地址
* bind的IP为'localhost'或'127.0.0.1'时,只允许本地回环接口的连接,即服务端和客户端运行在同一台机器上
*/
private bindTcpSocket() {
let localAddress = resolveIP(wifi.getIpInfo().ipAddress)
console.info("111111111 localAddress: " + localAddress);
//bind本地地址
tcpSocket.bind({ address: localAddress })
.then(() => {
console.info("111111111 绑定Tcp成功");
})
.catch(err => {
console.info("111111111 绑定Tcp失败,原因: " + err);
});
}
/**
* 发送消息数据
*/
private sendMessage() {
tcpSocket.getState().then((data) => {
console.info("111111111 连接状态: " + JSON.stringify(data))
//已连接
if (data.isConnected) {
//发送消息
tcpSocket.send({ data: `${this.inputContent}\n`, encoding: 'UTF-8' })
.then(() => {
this.messageReceive = this.messageReceive + "发送:" + this.inputContent + "\n"
console.info("111111111 消息发送成功");
})
.catch((error) => {
console.info("111111111 消息发送失败,原因:" + JSON.stringify(error));
})
} else {
console.info("111111111 没有连接");
this.connectMessage = '未连接,服务器断了'
}
})
}
/**
* 连接服务器
*/
private tcpSocketConnect() {
//开始连接
tcpSocket.connect({
address: { address: connectAddress.address, port: connectAddress.port, family: connectAddress.family },
timeout: 6000
}).then(() => {
console.info("111111111 tcpSocketConnect:连接成功");
let tcpExtraOptions: socket.TCPExtraOptions = {
keepAlive: true, //是否保持连接。默认为false
OOBInline: true, //是否为OOB内联。默认为false
TCPNoDelay: true, //TCPSocket连接是否无时延。默认为false
socketLinger: {
on: true,
linger: 10
}, //socket是否继续逗留。- on:是否逗留(true:逗留;false:不逗留)。- linger:逗留时长,单位毫秒(ms),取值范围为0~65535。当入参on设置为true时,才需要设置。
receiveBufferSize: 1000, //接收缓冲区大小(单位:Byte),默认为0
sendBufferSize: 1000, //发送缓冲区大小(单位:Byte),默认为0。
reuseAddress: true, //是否重用地址。默认为false。
socketTimeout: 3000//套接字超时时间,单位毫秒(ms),默认为0。
}
tcpSocket.setExtraOptions(tcpExtraOptions, (err: BusinessError) => {
if (err) {
console.log('111111111 setExtraOptions 失败');
return;
}
console.log('111111111 setExtraOptions 成功');
});
}).catch((error) => {
console.info("111111111 tcpSocketConnect 连接失败,原因: " + JSON.stringify(error));
})
}
/**
* 解析ArrayBuffer
*/
private resolveArrayBuffer(message: ArrayBuffer): string {
let view = new Uint8Array(message);
let textDecoder = util.TextDecoder.create()
let str = textDecoder.decodeWithStream(view);
console.info("111111111 message 缓存内容: " + str)
return str;
}
/**
* 关闭Socket监听和连接,释放资源
*/
private tcpSocketRelease() {
tcpSocket.off("message")
tcpSocket.off("connect")
tcpSocket.off("close")
tcpSocket.close()
tcpSocket = null
}
}
2、IpUtil.ets
export function resolveIP(ip: number): string {
if (ip < 0 || ip > 0xFFFFFFFF) {
throw ('The number is not normal!');
}
return (ip >>> 24) + '.' + (ip >> 16 & 0xFF) + '.' + (ip >> 8 & 0xFF) + '.' + (ip & 0xFF);
}
3、module.json5配置
因为涉及到网络访问,需要配置网络权限,在module.json5中配置
"requestPermissions": [
{
"name": "ohos.permission.INTERNET" //联网
},
{
"name": "ohos.permission.GET_NETWORK_INFO" //获取网络相关信息
},
{
"name": "ohos.permission.SET_NETWORK_INFO" //设置网络相关信息
},
{
"name": "ohos.permission.GET_WIFI_INFO" //获取wifi相关信息
}
]
服务器端Java代码
package org.example;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketService {
public static void main(String[] args) {
int port = 6666;
try {
// 创建ServerSocket对象,指定监听的端口号
ServerSocket serverSocket = new ServerSocket(port);
while (true) {
Socket clientSocket = serverSocket.accept();
System.out.println("客户端连接: " + clientSocket.getInetAddress().getHostAddress());
BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter writer = new PrintWriter(clientSocket.getOutputStream(), true);
String message;
while ((message = reader.readLine()) != null) {
System.out.println("从客户端接收到的消息: " + message);
writer.println("回复: " + message);
}
reader.close();
writer.close();
clientSocket.close();
System.out.println("连接断开");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}