将数据包发送到源专用服务器
Send packets to Source Dedicated Server
我正在尝试用 dart 编写一个 RCON 客户端,但我遇到了问题:
服务器收到了数据包,但似乎无法正确读取它作为回复我得到:
Rcon auth failed from rcon whitelist address 2.xxx.xxx.169:52672
即使密码正确:
"rcon_password" = "foo" ( def. "" ) - remote console password.
我在代码注释中提供了指向 valve's wiki 的链接。
这是我目前的代码:
Socket socket;
int _id = 1;
const int SERVERDATA_AUTH = 3;
const int SERVERDATA_AUTH_RESPONSE = 2;
const int SERVERDATA_EXECCOMMAND = 2;
const int SERVERDATA_RESPONSE_VALUE = 0;
void main() async {
socket = await Socket.connect('hexah.net', 27015);
await socket.listen(onSocketData, onError: onError, onDone: onDone);
await _write(SERVERDATA_AUTH, 'foo');
}
void _write(int type, String body) async {
var bodyASCII = ascii.encode(body); //Get ASCII string with Null terminator
// Should I use this or the other way? ??
var size = bodyASCII.length + 14;
var buffer = new Int8List(size).buffer;
var bdata = new ByteData.view(buffer);
bdata.setInt32(0, size - 4, Endian.little); //Byte requests length (32bit le signed int).
bdata.setInt32(4, _id, Endian.little); //Any integer (32bit le signed int).
bdata.setInt32(8, type, Endian.little); //Valid values: SERVERDATA_* (32bit le signed int).
int writepos = 12;
await bodyASCII.forEach((element) {
bdata.setInt8(writepos, element);
writepos +=1;
});
bdata.setInt16(size-2, 0, Endian.little); //Write the null terminators
await socket.write(bdata);
_id++;
}
void onSocketData(var data){
print(data);
}
void onError(var data, StackTrace stack){
print(stack);
}
void onDone(){
print('Connection terminated');
}
这里还有一个小例子 nodejs:
var size = Buffer.byteLength(body) + 14,
buffer = new Buffer(size);
buffer.writeInt32LE(size - 4, 0);
buffer.writeInt32LE(id, 4);
buffer.writeInt32LE(type, 8);
buffer.write(body, 12, size - 2, "ascii");
buffer.writeInt16LE(0, size - 2);
你有什么想法吗?
特别是关于正确获得长度。
packet payload 应该是这样的
使用 RawSocket
我得到这个回复:
RawSocketEvent.write
RawSocketEvent.readClosed
编辑:
我看到从 nodejs 发送的相同数据包导致身份验证成功,但 Dart 失败,知道为什么会这样吗? (将数据包从 nodejs 和 dart 转换为数组,结果相同)
已解决!
问题是我必须使用 RawSocket 并编写如下内容:
var packet = bdata.buffer.asInt8List();
await socket.write(packet, 0, packet.length);
我正在尝试用 dart 编写一个 RCON 客户端,但我遇到了问题:
服务器收到了数据包,但似乎无法正确读取它作为回复我得到:
Rcon auth failed from rcon whitelist address 2.xxx.xxx.169:52672
即使密码正确:
"rcon_password" = "foo" ( def. "" ) - remote console password.
我在代码注释中提供了指向 valve's wiki 的链接。
这是我目前的代码:
Socket socket;
int _id = 1;
const int SERVERDATA_AUTH = 3;
const int SERVERDATA_AUTH_RESPONSE = 2;
const int SERVERDATA_EXECCOMMAND = 2;
const int SERVERDATA_RESPONSE_VALUE = 0;
void main() async {
socket = await Socket.connect('hexah.net', 27015);
await socket.listen(onSocketData, onError: onError, onDone: onDone);
await _write(SERVERDATA_AUTH, 'foo');
}
void _write(int type, String body) async {
var bodyASCII = ascii.encode(body); //Get ASCII string with Null terminator
// Should I use this or the other way? ??
var size = bodyASCII.length + 14;
var buffer = new Int8List(size).buffer;
var bdata = new ByteData.view(buffer);
bdata.setInt32(0, size - 4, Endian.little); //Byte requests length (32bit le signed int).
bdata.setInt32(4, _id, Endian.little); //Any integer (32bit le signed int).
bdata.setInt32(8, type, Endian.little); //Valid values: SERVERDATA_* (32bit le signed int).
int writepos = 12;
await bodyASCII.forEach((element) {
bdata.setInt8(writepos, element);
writepos +=1;
});
bdata.setInt16(size-2, 0, Endian.little); //Write the null terminators
await socket.write(bdata);
_id++;
}
void onSocketData(var data){
print(data);
}
void onError(var data, StackTrace stack){
print(stack);
}
void onDone(){
print('Connection terminated');
}
这里还有一个小例子 nodejs:
var size = Buffer.byteLength(body) + 14,
buffer = new Buffer(size);
buffer.writeInt32LE(size - 4, 0);
buffer.writeInt32LE(id, 4);
buffer.writeInt32LE(type, 8);
buffer.write(body, 12, size - 2, "ascii");
buffer.writeInt16LE(0, size - 2);
你有什么想法吗? 特别是关于正确获得长度。
packet payload 应该是这样的
使用 RawSocket
我得到这个回复:
RawSocketEvent.write
RawSocketEvent.readClosed
编辑:
我看到从 nodejs 发送的相同数据包导致身份验证成功,但 Dart 失败,知道为什么会这样吗? (将数据包从 nodejs 和 dart 转换为数组,结果相同)
已解决! 问题是我必须使用 RawSocket 并编写如下内容:
var packet = bdata.buffer.asInt8List();
await socket.write(packet, 0, packet.length);