All I want for Christmas is an IP Address

So, here I sit, trying to make the best darned network services infrastructure for my screen sharing application.  Basically, I want a simple service front end that can take thousands of connections on the internet, and do some amount of processing, shuffling bit back and forth between the various connections.

There are two constraints.  Lua has to be in the mix, because I’m just nuts, and I must use Windows, because I’m doubly nuts.

So, at first blush, you might think, “hay, just use LuaSockets, and you’re done!

Well, yes, and no, and maybe not at all.  I haven’t examined the LuaSocket code closely, but my guess is that it uses standard Berkeley sorts of sockets.  I am further guessing that it doesn’t delve deeply into using I/O completion ports.  Well, that’s the model that I want, I/O completion ports!  They have proven to be the most robust in terms of scalability vs resource utilization.

So, then you might chime, “hay, why don’t you use the ASIO/Boost library, there’s surely a Lua binding to that!!  Well, yah, I could do that, and add a few Klines of code to my project, which is not needed.  Going that route would once again leave me in the “waiting for someone else to fix bugs and advance their code” category, which I don’t want.

Being the engineer that I am, I decided to wrap the Windows networking calls, from scratch…

I have a lot of history here.  I did similar with C# and the .net frameworks, although the networking stack already existed.  It was a training exercise.  Once more into the breach!  And I find things are just as funky as they were the last time around.  It’s fun to go trapsing through old APIs from a bygone era.  Those functions where you’re passing in a structure pointer, as well as the size of the structure, so the routine can figure out what the structure might actually represent.  Those return values that are pointers to arrays that might hold your values, etc.

I’m glad to be using Lua.  There are some advantages this time around as compared to when I did this in C#.  For example, the Winsock2.h header file defines a SOCKET thus:

typedef UINT_PTR        SOCKET;

Simple enough.  So, I do the same in Lua:

ffi.cdef[[
typedef UINT_PTR        SOCKET;
]]

Then, there’s all the attendant Berkeley style socket calls, you know: accept, connect, bind, listen, send, recv, etc.  So, I’m thinking, even though I’m headed to completion port nirvana, I might as well, create some convenience classes for those cases where I’m not writing server side code, but rather simple client side stuff.  So:

local BSocket local BSocket_mt = {
__index = {
-- Create a new socket
Create = function(self, af, stype, protocol)
local socketValue = winsock.socket(af, stype, protocol)
return BSocket(socketValue)
end,

Accept = function(self, addr, addrlen)
local newsock = winsock.accept(self,addr,addrlen);
return BSocket(newsock)
end,

Bind = function(self, name, namelen)
local err = winsock.bind(self, name, namelen);
return err   end,

},
}
BSocket = ffi.metatype(“SOCKET”, BSocket_mt)

That works fairly well.  I haven’t yet defined the IPEndPoint object yet, but once that’s done, I’ll be able to do:

local mySocket = BSocket():Create(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
mySocket:SendTo(buf, host)

That’s fairly simple I think.  But, before I get there, I have to deal with IPV4 address translation, like going from ‘dot’ notation to an integer in network byte order (inet_addr), as well as get an host entry using a name, through DNS (gethostbyname).  With those pieces, then I can stitch together the address stuff, and I won’t have to monkey around with structures, and their sizes.

Since I’ve already done the buffer with length object, I can handily pass that around to routines without much fuss.  And similarly, I’ve already constructed a streaming interface for that buffer object, so I can handily stuff buffers with things like screen shot snippets, or what have you.

Parsing URLs might be on the list, although I don’t currently need that.

All I want to do is see some graphics on the screen.  But, what I’m getting is a whole lot more, all written in Lua.  I’m finding it quite fun to actually be able to program against systems like Windows in a nice easily understandable way.  The interop thing is huge for me.  When I did this in C#, there was a lot of pain and suffering trying to go between the two different systems.  In Lua, since it has a natural connection to the C style of programming, it’s fairly easy.  You still have to do some work to hide stuff and come up with a uniform interface that makes sense.  But, it’s fairly straight forward work.

I like it also because once you get the interfaces properly wrangled into the Lua world, it becomes mindlessly simple to stitch things together, because now you’re dealing with the benefits of having a nice dyanimic runtime to play with.

And so it goes.  Nothing to see here but the slow birth of a very highly performant piece of server code written in Lua.



Leave a comment