Convert Datagram Data To String HEX - dart

I'm Listening To UDP 6000 port and I want to convert incoming packages to Hex String
I searched but nothing found
Here is my code
import 'dart:io';
import 'package:udp/udp.dart';
main() async {
var sender = await UDP.bind(Endpoint.loopback(port: Port(42)));
var dataLength = await sender.send(
"Hello World!".codeUnits, Endpoint.broadcast(port: Port(21)));
stdout.write("${dataLength} bytes sent.");
var receiver =
await UDP.bind(Endpoint.unicast(InternetAddress.anyIPv4, Port(6000)));
await receiver.listen((datagram) {
print(datagram.data);
}, Duration(seconds: 200));
sender.close();
receiver.close();
}
#
my incoming package is like this:
[104, 101, 108, 108, 111]
I want to Convert to this
68656c6c6f
thanks

You can use the toRadixString to convert to values to hex, and the map the list.
var hex = datagram.data.map((e) => e.toRadixString(16));
print(hex);

Related

Dart Web Request and Response as a Stream of data

I have been trying to setup an HTTP connection from a Dart client to a Dart Server using the HttpServer and HttpClient classes respectively.
I want to use this connection to transmit event updates to the client whenever the server feels necessary, so the connection needs to be continuous and the response needs to be sent in chunks, not buffered.
I tried this approach using two different server configurations (once with HttpServer, once with Shelf), but both times the response awaited closing and then the data was printed by the client.
Here is my server code:
var httpsServer = await io.HttpServer.bind("127.0.0.1", 4001);
httpsServer.listen((request) {
request.response.bufferOutput = false;
request.response.headers.add("Content-Type", "text/event-stream");
request.response.headers.add("Cache-Control", "no-cache");
request.response.headers.add("Connection", "keep-alive");
// asynchronously write "Hello" every 100 ms
Timer.periodic(Duration(milliseconds: 100), (Timer timer) {
try {
request.response.write("Hello\n");
} catch (_) {
timer.cancel();
}
});
await Future.delayed(Duration(seconds: 3));
request.response.close();
});
And another using shelf:
{
var handler = const Pipeline().addMiddleware(logRequests()).addHandler(_echoRequest);
var server = await serve(handler, '127.0.0.1', 4000);
server.autoCompress = true;
}
FutureOr<Response> _echoRequest(Request request) {
Stream<List<int>> stream = Stream.periodic(Duration(milliseconds: 100), (int i) {
return utf8.encode("Hello\n");
}).take(10);
return Response.ok(stream);
}
However, on the client, I only receive the data once the connection has been closed:
HttpClient client = HttpClient()..badCertificateCallback = ((X509Certificate cert, String host, int port) => true);
HttpClientRequest request = await client.postUrl(Uri.parse('https://---/'));
request.headers.add('Content-Type', 'text/event-stream');
HttpClientResponse response = await request.close();
// use startChunkConversion to convert the stream of bytes to a stream of strings
Stream<String> stream = response.transform(utf8.decoder).transform(const LineSplitter());
await for (String line in stream) {
print(line);
}
Am I doing something wrong or would I be better off with a different library / approach?

How to run 2 process and exchange input/output between them multiple times?

I'm trying to do something like this:
Future<String> getOutAndAnswer(testcase) async {
Process python = await Process.start('python', ['tasks/histogram/run.py']);
Process java = await Process.start('java', ['solutions/Histogram.java']);
String results = "";
for(int i = 0; i < testcase; i++){
final String out = await python.stdout.transform(utf8.decoder).first;
java.stdin.writeln(out);
final String answer = await java.stdout.transform(utf8.decoder).first;
python.stdin.writeln(answer);
results += "($out, $answer)";
}
return results;
}
Basically, the python program is responsible for generating the input of each test case, then the java program will take the input and return the answer, which is sent to the python program to check if it's correct or not, and so on for every test case.
But when I try to use the above code I get an error saying I've already listened to the stream once:
Exception has occurred.
StateError (Bad state: Stream has already been listened to.)
Python program:
import os
CASE_DIR = os.path.join(os.path.dirname(__file__), "cases")
test_cases = next(os.walk(CASE_DIR))[2]
print(len(test_cases))
for case in sorted(test_cases):
with open(os.path.join(CASE_DIR, case), 'r') as f:
print(f.readline(), end='', flush=True)
f.readline()
expected_output = f.readline()
user_output = input()
if expected_output != user_output:
raise ValueError("Wrong answer!")
print("EXIT", flush=True)
Java program:
public class Histogram {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int t = scanner.nextInt();
for (int i = 0; i < t; i++) {
String input = scanner.nextLine();
String answer = calculateAnswer(input);
System.out.println(answer);
}
}
}
Your issue is with .first which is going to listen to the stream, get the first element, and then immediately stop listening to the stream. See the documentation here: https://api.dart.dev/stable/2.17.3/dart-async/Stream/first.html
You should instead listen once and define an onData method to perform the steps. See the documentation for .listen() here: https://api.dart.dev/stable/2.17.3/dart-async/Stream/listen.html
You could try wrapping the stdout streams in StreamIterator<String>. You will have to give it a try to verify, but I think this is what you are looking for.
Future<String> getOutAndAnswer(int testcase) async {
Process python = await Process.start('python', ['tasks/histogram/run.py']);
Process java = await Process.start('java', ['solutions/Histogram.java']);
String results = "";
StreamIterator<String> pythonIterator = StreamIterator(
python.stdout.transform(utf8.decoder).transform(LineSplitter()));
StreamIterator<String> javaIterator = StreamIterator(
java.stdout.transform(utf8.decoder).transform(LineSplitter()));
for (int i = 0; i < testcase; i++) {
if (await pythonIterator.moveNext()) {
final String out = pythonIterator.current;
if (out == 'EXIT') {
break;
}
java.stdin.writeln(out);
if (await javaIterator.moveNext()) {
final String answer = javaIterator.current;
python.stdin.writeln(answer);
results += "($out, $answer)";
}
}
}
await pythonIterator.cancel();
await javaIterator.cancel();
return results;
}
You may need to add the following imports:
import 'dart:async';
import 'dart:convert';

How to encode a string into windows-1251 charset?

How can I encode a string into windows-1251 charset?
I'm going to post a form data into a backend, which internaly uses windows-1251, so I need to encode a string properly so that the message will be readable in the backend.
Here's how I send it
final codec = const Windows1251Codec(allowInvalid: false);
final encoded = codec.encode(message);
print('${codec.name}: encode "$message" to "$encoded"');
Response r = await Requests.post('http://abackend.com/page.php?action=send',
body: {'body': encoded},
bodyEncoding: RequestBodyEncoding.FormURLEncoded
);
console:
I/flutter ( 7423): windows-1251: encode "привет" to "[239, 240, 232,
226, 229, 242]"
There is a package that can do this called enough_convert.
Usage example:
import 'package:enough_convert/enough_convert.dart';
void main() {
final codec = const Windows1251Codec(allowInvalid: false);
final input = 'To encode input';
final encoded = codec.encode(input);
}

How to encode an Urdu string in Dart?

I extract an Urdu text from a web adress. For example, my text is فروردین. But when I print it, I see 'ÙرÙردÛÙ'. How can I print it correctly?
import 'dart:convert';
import 'package:http/http.dart';
import 'package:html/parser.dart';
import 'package:html/dom.dart';
Future initiate() async {
var client = Client();
Response response = await client.get('https://www.varzesh3.com/');
var document = parse(response.body);
List<Element> links = document.querySelectorAll('tr.match-date > td.text-center');
for (var link in links) {
print(link.text)
//var bytes = utf8.encode(link.text);
}
The problem seems to be the client don't recognize the charset of the page and defaults to latin1. Please take a look at the following code where I force using UTF-8 instead by taking the respond as bytes and convert them to UTF-8 by using the utf8 decoder.
import 'dart:convert';
import 'package:http/http.dart';
import 'package:html/parser.dart';
import 'package:html/dom.dart';
main() async {
var client = Client();
Response response = await client.get('https://www.varzesh3.com/');
var document = parse(utf8.decode(response.bodyBytes), encoding: "utf8");
List<Element> links = document.querySelectorAll(
'tr.match-date > td.text-center');
for (var link in links) {
print(link.text);
}
}

How do I open and follow a file in Dart (like tail -f)?

Is there an easy way to open a file and continously read from it without the stream getting closed on EOF? Like the Unix command tail -f.
Just reading until EOF is described in the API docs. But I can't see an obvious/simple way to block or pause the stream for more input.
One solution would be to repeatedly reopen the file and continue reading from the last known length when I detect that the file size has changed.
Somethink like this
import 'dart:io';
void main(List<String> args ) {
var file = new File("test.txt");
print(file.absolute);
var openFuture = file.open(mode: FileMode.READ);
openFuture.then((raf) => raf.length().then((len) => raf.setPosition(len)
.then((raf) => raf.readXxx...
}
You can also use Directory.watch to get notified about changes and then reopen and read from the last known position.
(even though this questions is a bunch of years old now, I stumbled across the same issue today and couldn't find a viable solution and therefore had to roll my own and wanted to share my findings with future generations of Dart programmers. ;-))
The dart:io package in conjunction with a bit of stream and async-await magic should offer everything that is needed to achieve a "tail -f"-like functionality:
import 'dart:typed_data';
import 'dart:io';
Stream<List<int>> tail(final File file) async* {
final randomAccess = await file.open(mode: FileMode.read);
var pos = await randomAccess.position();
var len = await randomAccess.length();
// Increase/decrease buffer size as needed.
var buf = Uint8List(8192);
Stream<Uint8List> _read() async* {
while (pos < len) {
final bytesRead = await randomAccess.readInto(buf);
pos += bytesRead;
yield buf.sublist(0, bytesRead);
}
}
// Step 1: read whole file
yield* _read();
// Step 2: wait for modify events and read more bytes from file
await for (final event in file.watch(events: FileSystemEvent.modify)) {
if ((event as FileSystemModifyEvent).contentChanged) {
len = await (randomAccess.length());
yield* _read();
}
}
}
This function (tail) might then be used like that:
import 'dart:convert';
import 'dart:io';
void main() {
final file = File('/var/log/messages');
tail(file).transform(utf8.decoder).transform(LineSplitter()).forEach((line) {
// Do something with the line that has been read, e.g. print it out...
print(line);
});
}

Resources