Network in phobos

Adam D. Ruppe destructionator at gmail.com
Mon Mar 29 07:42:35 PDT 2010


On Sun, Mar 28, 2010 at 12:37:14PM -0700, Igor Lesik wrote:
> IMHO, such oversimplified approach is not very useful.

Depends on your needs. A lot of time, I just want to quickly whip
something together that fetches something, and I don't care how long
it takes*. It's the kind of thing I'd use the nc program on the linux
command line to do, but right there in the D.

* If I do care how long it takes, I'll just fork() the whole program and
let the child to it. I'm thinking about making a generic background!(delegate)
template that can do this automatically, but D2 should have threads that work
just as well soon anyway.


One example is I needed something very simple that speaks SMTP. I wrote
it in my fancier network library, and it was a fair amount of code that
was a bit overcomplicated.

With this kind of thing, it is a fairly brief list of writefln and readln
lines.

> Yes, it would be so nice to have a good network library, but many things
> have to be considered in order to cook decent library. One important
> aspect is support for asynchronous calls; for example TCP/UDP stuff
> in Boost is placed in to ASIO package.


In my fancier library <http://arsdnet.net/dcode/netman.d>, which needs some
work still to finish, but is usable, all write and read calls go to a buffer.

By the way, everything in my dcode directory there is free for the taking
if anyone wants it.

Anyway, you do something like this:

class MyConnection : Connection {
    override void onDataReceived() {
        auto a = read(); // gets the buffer of new data

        write("some data"); // puts that in the outgoing buffer. not
			   // actually written until the function returns

    	changeReadPosition(pos); // discards [0..pos] of the internal
    				// buffer, so the next time you get
    				// called, you deal with leftover info.
    				// good for handling incomplete requests
	}
}

The incoming and outgoing buffers aren't actually put on the network until
the next call to NetworkManager.proceed(). So your main has to look something
like this:

void main() {
	auto netman = new NetworkManager;
	netman.connect("site.com", 80);
	while(netman.proceed()) { }
}

The nice thing about the network manager class is it does incoming connections
too:

void main() {
	auto netman = new NetworkManager;
	netman.listen(80);
	while(netman.proceed() { }
}


And each incoming connection is a particular specialization of the Connection
class (which you create in a delegate, not shown here), which handles all the
work. netman.proceed() calls select() on all its sockets, then calls the
appropriate handler based on what happens: onDataReceived, onDisconnect, etc.





The downside is my read() and write() functions are very simple, and kinda
suck, and every call is async, so even if you don't care about speed, you
have to code it with all your functions returning instantly.

The various functions and ranges in the stdio File are much easier to work
with for lots of things.

Ideally, what I think would be nice is having File available for when you
want it, and then being able to attach it to a NetworkManager kind of thing
which adds async calls to the interface.

Or something like that. Maybe the one size can't really fit all, but I'd like
to have both options available somehow.

> As long as you use only socket API there is no problem to write generic
> code for Linux and Windows. Windows socket API even has select() function.

Cool. Most my code is just simple socket stuff, so it should be easy to
port then.


-- 
Adam D. Ruppe
http://arsdnet.net



More information about the Digitalmars-d mailing list