tags:

views:

46

answers:

1

I want to write code in C# similar to following code in perl. What the code does is sends a message through UDP socket and requests for a TCP Port. The code in perl is as below:

# Get a UDP connection to port

$proto = getprotobyname('udp');
    no strict 'refs';
    $udpS = "UDP Socket";
if ( !socket($udpS, AF_INET, SOCK_DGRAM, $proto)) {
        $errMsg = "Can't create UDP socket (to $hostname) [$!]";
        return (0, $errMsg);
}

# Bind this socket to an address.
my $this = pack("S n a4 x8", AF_INET, 0, "\0\0\0\0"); # '

if ( ! bind($udpS, $this) ) {
        $errMsg = "Can't bind UDP socket (to $hostname) [$!]";
        return (0, $errMsg);
}

# Request TCP port

# remote host
    my $len = 0;  # to suppress warnings
    $iaddr = gethostbyname($hostname);

if ( !defined( $iaddr )) {
    $errMsg = "gethostbyname failed on $hostname";
    shutdown($udpS,2);
    close($udpS);
        return (0, $errMsg);
}

    $sin = sockaddr_in($port, $iaddr);
# attempt 5 times to get the TCP port before failing
foreach (0..4) {
    if ( !send($udpS, 1, 0, $sin)) {
        $errCodeMsg = 
            "Can't send on UDP socket (to $hostname), [$!]";
        shutdown($udpS,2);
        close($udpS);
            return (0, $errCodeMsg);
        }

    my $msg = "";
        if( recv($udpS, $msg, 2, 0) ) {
                    ($tcpPort) = unpack('n',$msg);
            # ($tcpPort) = unpack('S',$msg);
            last;
        } else {
            sleep(1);   # wait a second!
        }
}

I wrote following code in C#:

IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(host),port);
Socket soUdp = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);               

            for (int i = 0; i < 5; i++)
            {

                int temp = 1;                   
                byte[] data = BitConverter.GetBytes(temp);

                soUdp.SendTo(data, data.Length, SocketFlags.None, endPoint);

                IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
                EndPoint Remote = (EndPoint)sender;

                data = new byte[1024];
                int recvLength = soUdp.ReceiveFrom(data, ref Remote);
                data = ReverseBytes(data); //takes care of Endian ness.

                Console.WriteLine("Message received from {0}", Remote.ToString());
                Console.WriteLine("Port is:" + BitConverter.ToInt32(data, 0));

            }

In perl i get the write port number. But in C# i always get port as 0. Can anyone figure out what am i doing wrong?

A: 

You need to call Socket.Bind(EndPoint localEP) before using ReceiveFrom()

And do you not need to create a seperate socket for send and receive?

Then it seems to work for me!

Dog Ears