Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

UDP socket with Tango

Moderators: larsivi kris

Posted: 04/17/08 18:17:21

Hi,

I'm trying to create a bare bones UDP program that sends and receives data on a given local port. I wrote a short program, which compiles, runs and returns data, but instead of connecting and sending/receiving it does something else and continues without error whether or not there's something to listen to or not. To prove I'm not going crazy I implememted a very similar C# program running as I wished and that program works fine. Do you have an idea what I can do to make this piece of code work?

private import  tango.io.Console;

private import  tango.net.Socket, 
                tango.net.InternetAddress;
private import tango.io.Stdout;


void main()
{
        auto socket = new Socket(AddressFamily.INET, SocketType.DGRAM, ProtocolType.UDP);
        socket.blocking = false;
        auto localEndpoint = new InternetAddress ("localhost", 1979);
        socket.bind(localEndpoint);
        
        byte[8] cmd;
        cmd[0] = cast(byte)'a';
        cmd[1] = cast(byte)'b';
        cmd[2] = cast(byte)'c';
        cmd[3] = cast(byte)'d';
        cmd[4] = cast(byte)'e';
        cmd[5] = cast(byte)'f';
        cmd[6] = cast(byte)'g';
        cmd[7] = cast(byte)'h';

		byte[] buf = new byte[cmd.length];
		
        int res = socket.sendTo(buf, new InternetAddress ("localhost", 1979));
        
        byte[] inBuf = new byte[1026];
        
        while (1) {
        	int res2 = socket.receiveFrom(inBuf, new InternetAddress ("localhost", 1979));
	        Stdout (res);
        }
        
}
Author Message

Posted: 04/17/08 19:25:12

Don't use Socket :)

DatagramSocket exists for UDP usage, and should do what you need

Posted: 04/17/08 20:41:23 -- Modified: 04/17/08 20:45:32 by
HienTau

Hi kris,

Thanks for the quick reply. I rewrote the snippet to use DatagramConduit? (I guess that's what you meant) and also bound the conduit to localhost, but the result is basically the same. Though there's no UDP-packet sending software started, write() returns with "8" although some sort of error should have occured. The software I'm trying to communicate with needs those eight byte send before it allows reading data, so I guess write() somehow fails..?!

This is the code now:

private import  tango.io.Console;

private import  tango.net.DatagramConduit, 
                tango.net.InternetAddress;
private import tango.io.Stdout;


void main()
{
	Stdout("creating conduit");
        auto con = new DatagramConduit();
        
        Stdout ("binding...");
        con.bind(new InternetAddress(InternetAddress.ADDR_ANY, InternetAddress.PORT_ANY));
        
        byte[8] cmd;
        cmd[0] = cast(byte)'a';
        cmd[1] = cast(byte)'b';
        cmd[2] = cast(byte)'c';
        cmd[3] = cast(byte)'d';
        cmd[4] = cast(byte)'e';
        cmd[5] = cast(byte)'f';
        cmd[6] = cast(byte)'0';
        cmd[7] = cast(byte)'1';

	byte[] buf = new byte[cmd.length];
		
	Stdout("Trying to write...");
        int res = con.write(buf, new InternetAddress ("127.0.0.1", 1979));
        Stdout("sent result: ", res);
        
        byte[] inBuf = new byte[1026];
        
        while (1) {
		Stdout("trying to read...");
        	int res2 = con.read(inBuf, new InternetAddress ("127.0.0.1", 1979));
		Stdout ("result: ", res2);
        }
        
}

Be aware that Stdout is blocked by con.read() and only shows when the read statement is removed or commented out.

Posted: 04/18/08 06:22:10

have you tried the little example at the end of DatagramConduit? That works here, so I'd be interested to hear if it doesn't work for you

Posted: 04/18/08 10:59:37 -- Modified: 04/18/08 11:14:21 by
HienTau

Hi kris,

That example solved the problem. The code is now:

import tango.io.Console;

import tango.net.InternetAddress,
		tango.net.DatagramConduit,
		tango.io.Stdout;

void main()
{
        auto addr = new InternetAddress (InternetAddress.ADDR_ANY, InternetAddress.PORT_ANY);

        // listen for datagrams on the local address
        auto gram = new DatagramConduit;
        gram.bind (addr);

		byte[8] cmd;
        cmd[0] = cast(byte)'a';
        cmd[1] = cast(byte)'b';
        cmd[2] = cast(byte)'c';
        cmd[3] = cast(byte)'d';
        cmd[4] = cast(byte)'e';
        cmd[5] = cast(byte)'f';
        cmd[6] = cast(byte)'0';
        cmd[7] = cast(byte)'1';

		byte[] buf = new byte[cmd.length];       
        gram.write (cmd, new InternetAddress("127.0.0.1", 1979));

        char[1026] tmp;
        auto x = new InternetAddress;
        
        while (1) {
	        auto bytes = gram.read (tmp, x);
	        for (int i = 0; i < tmp.length; i++) {
	        	Stdout (cast(int)tmp[i]);
	        }
        }
}

The nitty gritty difference to the former code is that variable x has no address or port assigned. Now data is sent and received as expected. Thank you very much for your help!

Posted: 04/18/08 17:21:52

you're most welcome :)