herman58 has asked for the wisdom of the Perl Monks concerning the following question:

I have to talk to a network attached physical terminal where people register their working hours with RFID chips.
The IP is 192.168.XXX.16 Port 10001.

The Protocol expects these ASCII control chars:

CharDECHEXDescription
<STX>00202Start of Telegram
<SOH>00101Start of Answer (Ethernet)
<ETX>00303End of Data Bloc
<EOT>00404End of Telegram
<ENQ>00505Data available
<ACK>00606Command understood
<NAK>02115Command not understood

To get me startet I need to send these values to the terminal:

<ATX>H<EOT>

Control-Char-STX + Command-char "H" as string + Control-Char-EOT

How do I send this mixture of control chars and strings?
The terminal should send an answer like this:

<STX>XTM20<EOT>

Control-Char-STX + id+version 20 + Control-Char-EOT
Any help would be appreciated.
  • Comment on Sending ASCII Control Chars over TCP/IP socket

Replies are listed 'Best First'.
Re: Sending ASCII Control Chars over TCP/IP socket
by pryrt (Abbot) on Jun 27, 2019 at 16:04 UTC

    Assuming you already have your communication link established, just send the appropriate string to that link. perlrebackslash shows that you can send a hex byte thru the "\x##" sequence, so STX would be "\x02", and thus <STX>H<EOT> would be "\x02H\x04".

      Somehow it's working:
      #!/usr/bin/perl use IO::Socket; use strict; my( $socket,$ret ); my $maxlen = 1024; my $timeout = 5; # my $data = "\x02H\x04"; # getVersion <STX>CMD<EOT> my $data = "\x02LS9F\x04"; # getSerial <STX>CMD<CHECKSUM><EOT> $socket = IO::Socket::INET->new ( PeerAddr => '192.168.1.16', PeerPort => 10001, Proto => 'tcp' ) or die "ERROR in + Socket Creation : $!\n"; main::printdata('Client sends',$data ); $socket->send($data) or die "send: $!"; $socket->recv( $ret,$maxlen ); main::printdata('Server responded',$ret ); $socket->close();
      Result:
      Client sends \x02LS9F\x04
      Server responded \x0200000000030000000000C3\x04

      But when I add $socket->recv( $ret,$maxlen ) or die "Fail: $!"; the cmd always fails. with an empty error:
      Client sends \x02LS9F\x04
      Fail:

      How do I increase the verbosity level to find out what's going wrong here?
        How do I increase the verbosity level to find out what's going wrong here?

        Item 1 in the Basic debugging checklist suggests to use warnings which you are not doing here. Enable that for starters.

        $socket->recv( $ret,$maxlen ) or die "Fail: $!";

        The docs for recv say:

        Returns the address of the sender if SOCKET's protocol supports this; returns an empty string otherwise. If there's an error, returns the undefined value.

        But your statement only tests for truth rather than definedness. Try this instead, perhaps:

        $socket->recv( $ret,$maxlen ) // die "Fail: $!";
Re: Sending ASCII Control Chars over TCP/IP socket
by BillKSmith (Monsignor) on Jun 27, 2019 at 20:32 UTC
    You can use the actual ASCII names with a little help from the pragma use charnames.
    use strict; use warnings; use charnames ':full'; my $command = "\N{STX}H\N{EOT}"; my $reply = "\N{STX}XTM20\N{EOT}";
    Bill