The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

KCP - Perl extension for skywind3000/kcp

SYNOPSIS

  use KCP;

  sub output
  {
      my ($data, $user) = @_;

      $user->{socket}->send($data, 0);
  }

  ...

  my $kcp = KCP::new($conv, $user);

  $kcp->set_mode("fast")->set_output(\&output);

  ...

  # scheduled call

  $kcp->update($current_millisec);

  ...

  # to send user data

  $kcp->send($data);
  
  ...

  # to recv user data

  $kcp->recv($data, 65536);

  ...

  # input data of transport

  $socket->recv($data, 65536, 0);

  $kcp->input($data, 65536);

  ...

DESCRIPTION

extension for skywind3000/kcp.

new( $conv[, $user] )

Create a KCP instance, such as:

  my $kcp = KCP::new($conv, $user);

$conv is conversation ID of KCP. $user is user data and it will be deliveried to output subroutine (see KCP::set_output for more details). So you can send output data that is from kcp with $user.

The $user is optional, so you can do this:

  my $kcp = KCP::new($conv);

But normally to provide it.

Finally, return instance of 'KCP' upon successful, otherwise return undef.

set_output( &output )

Set a callback for send data. The callback will be invoked When KCP want to send data.

  sub my_output
  {
      my ($data, $socket) = @_;

      $socket->send($data, 0);
  }

  ... # include creating a socket

  my $kcp = KCP::new($conv, $socket)
              or die "KCP::new is failed\n";

  $kcp->set_output(\&my_output); # set callback

  ...

As shown above, deliver a $socket to my_output subroutine and send data with the $socket.

output parameter is a referrence of subroutine and carry 2 parameters: $data and $user. The $user is from KCP::new.

Finally, it return instance of KCP. So you can do this:

  $kcp->setoutput(\&my_output)->update($current);

set_mode( $mode )

Set mode of KCP. mode "normal" and "fast" was be supported.

  set_mode("normal"); 

or

  set_mode("fast");

"normal" is equal to

  $kcp->nodelay(
      nodelay   => 0,
      interval  => 40,
      resend    => 0,
      disable_congestion_control => 0
  );

"fast" is equal to

  $kcp->nodelay(
      nodelay   => 1,
      interval  => 10,
      resend    => 2,
      disable_congestion_control => 1
  );

see KCP::nodelay for more details.

nodelay( [%options] )

Extension for ikcp_nodelay(). It is flexible for controlling to KCP.

  $kcp->nodelay(
      nodelay                    => ...,
      interval                   => ...,
      resend                     => ...,
      disable_congestion_control => ...,
  );

Throw a exception if given options is invalid, otherwise return instance of KCP. So you can do this:

  $kcp->nodelay(nodelay => 1)->setoutput(\&my_output);

or to catch exception

  local $@;

  eval {
      $kcp->nodelay(nodelay => $nodelay_value);
  };

  if ($@) ...

option nodelay

Do enable nodelay mode? Valid value is 0 and 1. 0 represent to disable, 1 represent to enable. The default is 0 ( 'disable' ).

option interval

KCP interval of working, Unit is ms and default is 40ms

option resend

Do enable fast resend mode? Valid value is 0, 1 and 2. 0 represent to disable, 1 represend to enable, 2 represend to resend immediately if skip 2 ACK. The default is 0 ( 'disable' ).

option disable_congestion_control

Do disable congestion control? Valid value is 0 and 1. 0 represent enable, 1 represend disable. The default is 0 ( 'enable' ).

update( $current_time )

Extension for ikcp_update().

Unit of $current_time is ms. The subroutine will return instance of KCP.

  use KCP;
  use Time::HiRes qw/ gettimeofday /;

  sub get_current()
  {
      my ($seconds, $microseconds) = gettimeofday;

      return $seconds * 1000 + $microseconds;
  }

  ...

  $kcp->update(&get_current);

  ...

flush

Extension for ikcp_flush.

Flush immediately pending data. The subroutine will return instance of KCP.

  $kcp->flush;

send( $data )

Extension for ikcp_send().

Send $data of user to KCP. Return undef if has error occur.

  unless ($kcp->send($data))
  {
      // for error
  }

recv( $data, $len )

Extension for ikcp_recv.

Receive data of user to $data. Return undef for EAGAIN.

  unless ($kcp->recv($data))
  {
      // for EAGAIN...
  }

input( $data )

Extension for ikcp_input().

Push $data of transport layer to KCP. Return undef if has error occur.

  $socket->recv($data, 65536, 0); # receive data from socket

  $kcp->input($data)
    or return undef; # error

get_conv( [$data] )

Extension for ikcp_getconv().

Get conversation ID of the KCP instance if $data isn't be given. Otherwise Pick-up conversation ID from $data.

  my $conv = $kcp->get_conv;

or

  $socket->recv($data, 65536, 0); # receive data from socket

  ...

  my $conv = $kcp->get_conv($data); # pick-up ID from the data

  ...

get_interval

Get interval of the KCP instance.

  my $interval = $kcp->get_interval;

peeksize

Extension for ikcp_peeksize().

Peek the size of next user message and return.

  my $n = $kcp->peeksize;
  if ($n < $expect_max_size)
  {
      ...

      $kcp->recv($data, $expect_max_size);

      ...
  }

mtu( [$mtu] )

Extension for ikcp_setmtu().

Get MTU of the KCP instance if mtu isn't be given, Otherwise set MTU to $mtu and return old MTU. The default is 1400.

Get MTU:

  my $mtu = $kcp->mtu;

or set MTU:

  my $old_mtu = $kcp->mtu(1500);

Throw a exception if $mtu of given is invalid.

sndwnd( [$window_size] )

Extension for ikcp_wndsize().

Get send window size of the KCP instance if window_size isn't be given, Otherwise set send window size to $window_size and return old window size. The default is 32.

Get send window size:

  my $sndwnd = $kcp->sndwnd;

or set send window size:

  my $old_sndwnd = $kcp->sndwnd(64);

rcvwnd( [$window_size] )

Extension for ikcp_wndsize().

Get receive window size of the KCP instance if windows_size isn't be given, Otherwise set receive window size to $window_size and return old window size. The default is 128.

Get receive window size:

  my $rcvwnd = $kcp->rcvwnd;

or set receive window size:

  my $old_rcvwnd = $kcp->rcvwnd(64);

get_waitsnd

Extension for ikcp_waitsnd().

Gets the number of packages to be sent.

  if ($max_wait_num < $kcp->waitsnd)
  {
      // to close the session, maybe.
  }

SEE ALSO

AUTHOR

homqyy, <yilupiaoxuewhq@163.com>

COPYRIGHT AND LICENSE

MIT License

Copyright (C) 2022 homqyy

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.