Here is the scenario. I need to write some code that will act like a bridge receiving data via TCP connection and sending SNMP traps on. I don't have any control of the client and at some point will loose connection to the server computer so the code needs to be robust and self repairing. Here is how it should work

The client connects to server (port 1066 so doesn't need to run as root). Every so often it will send some data of the form

chr(1) + message type + data

If message type is "0" (zero) this is a poll message and the data is 4 bytes indicating the number of messages since last poll. The server will reply back in kind with the number of messages since last poll.

If message type is anything else then the data is between 30 and 200 odd bytes terminated with <CRLF>.

Now I have the basics here already. (The specs said the poll was also <CRFL> terminated but it isn't.) There are a couple of concerns and "requirements" that I need some guidance on.

I run the Perl script inside a shell wrapper that will restart the Perl should it terminate. This wrapper also ensures that the environment is set correctly.

<set up bits including point to database and other stuff> my $poll = 0; my $messages = 0; # make the socket my $socket = IO::Socket::INET->new( LocalHost => '<hostname>', LocalPort => 1066, Proto => 'tcp', Listen => 5, Reuse => 1, ) or die "Socket could not be created : $!"; # accept connections while (my $new_sock = $socket->accept()) { while (1) { say "Waiting!"; my $buf=""; # loop until start of message control (chr(1)) while (read($new_sock,$buf,1)) { last if $buf eq chr(1 +);} read($new_sock,$buf,1); if ($buf eq "0") { # handle the POLL message # byte 1 = ASCII start of header (1) # byte 2 = '0' - poll message ID # byte 3 = number of messages since last poll +- 4 bytes # following don't seem to be sent. # byte 7 = ASCII CR (13) # byte 8 = ASCII LF (10) # already have initial bytes now get payload read($new_sock,$poll,4); say "POLL : $poll"; SendPollReply($new_sock); SendSNMP("0","0","--",undef,undef); } else { # Other messages look like they are Cr/LF term +inated $buf .= <$new_sock>; $messages++; say "Buffer : $buf Poll : $poll Messages : +$messages"; # only send traps for message group "A" or "C" if ($buf =~ /([AC])(.{8})((\+\+|--))(\d{8})(.{ +10})/msx) { my $message_group = $1; my $station_code = $2; my $change_type = $3; my $date_time = $5; my $point_name = $6; SendSNMP($message_group,$station_code, +$change_type,$date_time,$point_name); } } } } close($socket); sub SendPollReply { my $new_sock = shift; # send the poll reply # byte 1 = ASCII start of header chr(1) # byte 2 = '0' - response message ID # byte 3 = number of messages since last poll - 4 bytes # byte 7 = Error status '0' if OK # byte 8 = ASCII CR (13) # byte 9 = ASCII LF (10) SendMessage( $new_sock,"0".sprintf("%04d",$messages)."0"); $messages=0; } # wrap message back to poller in required start/end characters sub SendMessage { my ($new_sock,$message) = @_; $message = chr(1).$message.chr(13).chr(10); say "REPLY : $message"; print $new_sock $message; }

In reply to Writing a simple TCP server and connection handling by tweetiepooh

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.