我正在尝试在 Flutter 中使用 udp 套接字作为服务器。我想将此套接字绑定在我的本地主机上的 6868 端口上,始终处于侦听状态。不幸的是,当我尝试从客户端发送某些内容时,它永远不会打印字符串“RECEIVED”。 这是代码:
static Future openPortUdp(Share share) async {
await RawDatagramSocket.bind(InternetAddress.anyIPv4,6868)
.then(
(RawDatagramSocket udpSocket) {
udpSocket.listen((e) {
switch (e) {
case RawSocketEvent.read:
print("RECEIVED");
print(String.fromCharCodes(udpSocket.receive().data));
break;
case RawSocketEvent.readClosed:
print("READCLOSED");
break;
case RawSocketEvent.closed:
print("CLOSED");
break;
}
});
},
);
}
我做错了什么吗?
反正这是客户端,写的是Lua:
local udp1 = socket.udp()
while true do
udp1:setpeername("192.168.1.24", 6868)
udp1:send("HI")
local data1 = udp1:receive()
if (not data1 == nil) then print(data1) break end
udp1:close()
end
我用另一台服务器测试了它,效果很好,所以我不认为客户端有问题。
谢谢!
如果它可以帮助您,这里是我的应用程序中的 SocketUDP(作为单例)的代码。 我在本地主机中使用它,效果非常好:
class SocketUDP {
RawDatagramSocket _socket;
// the port used by this socket
int _port;
// emit event when receive a new request. Emit the request
StreamController<Request> _onRequestReceivedCtrl = StreamController<Request>.broadcast();
// to give access of the Stream to listen when new request is received
Stream<Request> get onRequestReceived => _onRequestReceivedCtrl.stream;
// as singleton to maintain the connexion during the app life and be accessible everywhere
static final SocketUDP _instance = SocketUDP._internal();
factory SocketUDP() {
return _instance;
}
SocketUDP._internal();
void startSocket(int port) {
_port = port;
RawDatagramSocket.bind(InternetAddress.anyIPv4, _port)
.then((RawDatagramSocket socket) {
_socket = socket;
// listen the request from server
_socket.listen((e) {
Datagram dg = _socket.receive();
if (dg != null) {
_onRequestReceivedCtrl.add(RequestConvert.decodeRequest(dg.data, dg.address));
}
});
});
}
void send(Request requestToSend, {bool isBroadCast:false}) {
_socket.broadcastEnabled = isBroadCast;
final String requestEncoded = RequestConvert.encodeRequest(requestToSend);
List<int> requestAsUTF8 = utf8.encode(requestEncoded);
_socket.send(requestAsUTF8, requestToSend.address, _port);
}
}
编辑:按照下面的要求,这里有一些使用它的细节。
首先,请求定义:
import 'dart:io';
import 'dart:typed_data';
import 'package:remotepcmultitouch/enumRequest.dart';
// describe a network request
class Request
{
// the request ID
final ERequest _id;
// the request data list
final List<String> _datas;
// the request address (from/to)
final InternetAddress _address;
// binary data, optional
final Uint8List binaryData;
Request(this._id, this._datas, this._address, {this.binaryData});
ERequest get id => _id;
List<String> get datas => _datas;
InternetAddress get address => _address;
}
处理从套接字收到的请求:
SocketUDP().onRequestReceived.listen(onRequestReceived);
void onRequestReceived(Request request) {
switch (request.id) {
// process the request
}
}
使用 SocketUDP 发送请求:我的示例将触摸位置发送到服务器
// send request to server to send the new touch data
SocketUDP().send(Request(
ERequest.SEND_TOUCH_DATA,
[touchState.index.toString(), fingerID.toString(), percentX, percentY],
this.address));
那么 RequestConvert.encodeRequest 和 RequestConvert.decodeRequest 只是将 Request 对象转换为字符串或从字符串解码的实用函数,没什么特别的(有很多方法可以做到这一点)