About

This library implements uTorrent Transport Protocol with pure Dart , no any other native library.

codecov

More uTP informations please take a look BEP 0029.

How to use

UTP socket include ServerUTPSocket and UTPSocketClient.

Listening income connection:

  var serverSocket = await ServerUTPSocket.bind(InternetAddress.anyIPv4, portyoulike);

  serverSocket.listen((socket) {
    print('someone connect me');
    socket.listen((data) {
     // receive data
    });
  });

Connect remote:

  var client = UTPSocketClient();
  var socket = await client.connect(remoteAddress, remotePort);

  socket.listen((data) {
     // receive data
  });

Each UTPSocketClient can create mulitple UTP socket via connect method and each UTP socket share the same raw UDP socket , user can set the max UTP socket number (default is 5) when create UTPSocketClient instance.

Send data:

    socket.write(sometext); // write some text
    socket.writeln(sometext); // write some text with \n
    // write mulitple text together and sperate with ','
    socket.writeAll(sometextList,',');
    socket.add(somebyteslist); // send some List<int> data

The default text encoding is UTF-8 , user can set the encoding:

   socket.encoding = someencoding;

Even UTP socket use UDP to delivery the datas , but the UTP socket won't send the data 'one-by-one' , it will add the data into sending buffer , once there is avalidate window size , the socket will read the buffer data out with the avalidate size(less than the max packet size) and packet them together to send out.

on the other hand , If the sending data methods(add,write,etc...) are invoked in the same tick , these sending datas will be added in a cache , the socket will request to send them next tick.

For example:

    socket.write('u');
    socket.write('T');
    socket.write('P');

These methods are invoke in same tick , these datas ('u','T','P') will add into a cache (become 'uTP') and will be send next tick.

But it not means that remote will receive the 'uTP' in one packet , it depends the current window size.

Receive(listening) data:

   socket.listen((Uint8List data) {
     // receive data
   },
   onDone : (){
       // when remote or local socket closed , this method will be invoke
   },
   onError:(e){
       // when error happen,invoke this method
   });

Close the socket:

  await socket.close();

When invode the close method , the socket will send ST_FIN message to remote and waiting for the ack from remote , if user want to close it immediately , you can call this method :

  socket.destroy();

Actually , destroy method will send ST_RESET message to remote ,but it won't wait the ACK.

If socket close , it will wait for the expect ACK seq number, when the correct seq number received , the close method will completed future , or it will complete the future when timeout

Testing

Run tests:

dart test

Run tests with coverage:

dart test --coverage=coverage
dart run coverage:format_coverage --lcov --in=coverage --out=coverage/lcov.info --packages=.dart_tool/package_config.json --report-on=lib

Or use the provided script:

dart tool/coverage.dart

The coverage report will be generated at coverage/lcov.info and can be viewed with tools like genhtml or uploaded to services like Codecov.

Coverage is automatically uploaded to Codecov on every push and pull request via GitHub Actions.

Libraries

utp_protocol
UTP library , include ServerUTPSocket,UTPSocketClient,UTPSocket