http://www.perlmonks.org?node_id=324092
Sol-Invictus's user image
User since: Jan 26, 2004 at 07:12 UTC (20 years ago)
Last here: Feb 18, 2004 at 05:00 UTC (20 years ago)
Experience: 295
Level:Scribe (6)
Writeups: 35
Location:n/a
User's localtime: Apr 17, 2024 at 07:35 JST
Scratchpad: None.
For this user:Search nodes

A Work In Progress

Someone mentioned (hi bart!), I should be using my scratch pad for storing this stream of consciousness, but the name ("scratch pad") seems a little too transitory to me, like something you screw up into a spindle and throw away as soon as you're done with it - just not the spirit of things at all. The title of this node refers not only to my current on-going project but to the Great Work, alchemy of the soul. I am my work and my work is me, you see. So the space for my bio seemed more appropriate.

I'm not really a programmer, as in I have no formal programming background, but I look at the world with programmers eyes, and I love the challenge of applying a language to problem solving. One of the hardest things for me is dealing with the assumed background I don't have. Assumed by the manuals and pods in a lot of cases. Currently I'm working on a mud, hoping to hone a few skills. As such I'm moving into new areas, the first of which is Unix sockets, so I'm intending to keep a set of notes for each new area I start to look at, to help me, and ulteriorly others, achieve their goals, should theirs resemble mine.

Socket Hacking

Don't you just love the way the pods give you nicely rounded examples which rapidly polymorph into congealed masses of subroutines as you try to apply them to real world situations. And, just as surely, any document about sockets will start out chanting the mantra of the theory behind client and server programming and understanding this information will stand you in as good stead as the pod code examples. You understand both but you still can't use the info absorbed to do what you want. Jargon of course is the main strainer, winnowing the blessed from the profane. I'll add more terms as I come across ones I've never met before.

Socket Jargon file
Blocking
techie jargon for "sleep".
Out OF Band Data
stuff trying to sneak in through the backdoor rather than the socket i.e. system signals, key interrupts.
Multiplexing
running and managing multiple sockets from one process

Socket Errors

By setting a socket to non-blocking, you can effectively "poll" the socket for information. If you try to read from a non-blocking socket and there's no data there, it's not allowed to block--it will return -1 and errno will be set to EWOULDBLOCK.

note that in C errno isn't a boolean return value, but rather a variable. Under perl the errors get passed to $!

When performing non-blocking I/O on sockets, be careful to check for the error EWOULD BLOCK (stored in the global variable errno), which occurs when an operation would normally block, but the socket it was performed on is marked as non-blocking. In particular, accept, connect, send, recv, read, and write can all return EWOULDBLOCK, and processes should be prepared to deal with such return codes. If an operation such as a send cannot be done in its entirety, but partial writes are sensible (for example, when using a stream socket), the data that can be sent immediately will be processed, and the return value will indicate the amount actually sent.

Socket error messages

EACESS
created by trying to open a port number below 1024 without having ROOT privs
ENOBUFS
lack of memory(rare)
EPROTONOSUPPORT
unknown protocol
EPROTOTYPE
no protocol for socket requested
ETIMEDOUT
socket timeout
ECONNREFUSED
socket request bounced
ENETDOWN or EHOSTDOWN
someone pulled the plug or cable somewhere else
ENETUNREACH or EHOSTUNREACH
someone pulled the plug or cable attached to the server

The error messages above are purely for reference, they seemed important after looking at "Chapter 12: Networking with Sockets" in "Advanced Perl Programming" just below where it describes an implementation of a multiplexing server

"In any case, once this operation is carried out, sysread and syswrite return undef (not 0) and set $! to EAGAIN (or EWOULDBLOCK on BSD 4.3)"

Left me to wonder what the fork EAGAIN and EWOULDBLOCK were. To be fair the whole thrust of the Black Cat book is to embed perl in C apps to get the best of both worlds, so the author didn't really count on a tech illiterate like me trying to grok him.

Helpful in dealing with this dearth of knowledge on my part were:

Beej's Guide to Network Programming
It's for C programmers but Perl uses the same libraries, in name anyway, so it's easy to follow, and hell I like the guys writing style.

An Advanced 4.4BSD Interprocess Communication Tutorial
Altogether a heck of a lot crustier than Beej in style, though still relevant (BSD and all that).

Of course while I was rooting about for these on the net didn't I just happen on Grahm Barr's presentation notes for a talk he gave on sockets. Hope he doesn't want them back :).

So the real skinny is to do with IO buffering. OSen use buffering to deal with delays that would be caused by direct read/write disc access, basically dealing with memory is faster than dealing with disc read/writes. This means there are various layers of buffering between your s‎crip‎t and the OS. Normally a good thing, in the case of a network transaction it can cause "blocking", meaning one of the parties in a network dialog waits for their buffer to fill up, while really the rest of the s‎crip‎t/process expects the data to have been sent.

In the above situation a multiplexing socket rather than waiting, will return an error stating the socket would block if it followed through with the operation.

Why look at low level socket programming when there are nice modules to help make this easier

This is true in part - with the pods for IO::Socket and IO::Select I had a working TCP socket in minutes, but there is absolutely no documentation for how to use the listed socket and select options. The reasons for this that I can think of are basically:

(1) you already know how to do it with low level sockets programming libs and any explanation would be superfluous, if not redundant.
(2) Giving examples of how to use these options goes beyond the scope of the pod, which isn't a socket FAQ or cookbook.