Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

send call on udp socket

by saurabh.hirani (Beadle)
on May 04, 2009 at 15:28 UTC ( [id://761747]=perlquestion: print w/replies, xml ) Need Help??

saurabh.hirani has asked for the wisdom of the Perl Monks concerning the following question:

Hi guys,

I am writing a udp client-server system and during the work I found a problem which I wanted to discuss with you. It is best explained through this snippet:

use strict; use IO::Socket; my $client = new IO::Socket::INET( PeerAddr => '127.0.0.1', PeerPort => 3333, Proto => 'udp' ); (!$client) && die "failed to create sock: $!"; my ($request, $response); $request = 'sample req'; while(1 == 1) { if (! defined($client->send($request))) { print "send failed: $!\n"; } else { print "send succeeded\n"; } sleep 3; }

If there is no server on 3333, the output is pretty interesting:

send succeeded send failed: Connection refused send succeeded send failed: Connection refused . .

AFAIK, the reason why this would happen would be - in UDP the send system call cannot return the send status of the message as it is a blind throw. So if the message is within limits, the socket is okay, send returns true.

When the message is transmitted, if the host is not up we get a "connection refused" icmp error, which is captured in any of the sending/receiving operations I do later on and I get an error - the first send returned immediately after checking if the message can be sent. It can be. So after the first send and before the second, ICMP host not found was sent back. So the second send failed. Similarly it goes for the 3rd and 4th and so on.

My question:

How would you check the status of send sys call if you had to log an error if the host is down or something? (And no I don't want to use TCP :) ) - I was thinking of using Net::Ping module.

The output becomes all the more interesting if I configure a rule in iptables, telling it to drop icmp host unreachable responses. That way, the icmp response is dropped before it reaches my program and i get a "send succeeded" all the time, forever and ever, whether the host is up or down.

Replies are listed 'Best First'.
Re: send call on udp socket
by ig (Vicar) on May 05, 2009 at 04:57 UTC

    The send system call will give you an error if it failed to send the UDP packet. I would check the return value of the send function, as you are doing, to check the status of the send system call.

    Determining whether the packet was received and processed as intended at its destination is something quite different. For that I would have the receiving process return status via a return UDP packet. If you receive a reply, then you know the remote end received the packet and whether it was processed successfully or not. If you don't receive a reply, there might be a problem at the remote end, or there could be a network problem in the return path. You might resend after a timeout and repeat some reasonable number of times, after which you might assume a problem and log an error.

    You may need identifiers (e.g. sequence numbers) in your messages so that status messages can be correlated with sent messages. For example, if you send two messages and receive only one reply, you might need to know which of the two messages the reply corresponds to.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://761747]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (4)
As of 2024-04-25 16:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found