Things that irritate me about Python's socket module

May 20, 2006

I am afraid that I am too busy listening to the Men Without Hats to write too much tonight, so I am just going to trot out some of my irritations with Python's socket module. All of these are on Unix machines.

(I suspect that portability to Windows is the reason for some of these, but it doesn't mean that I'm not irritated by them.)

  • socket.error. Let me count the ways:

    • most instances should actually be IOError or OSError instead.
    • it has two entirely different formats; often the only sensible thing you can do with a socket error is to str() it.
    As a minimum there could be a socket.ioerror sub-class, like socket.herror, that guaranteed a single (errno, string) format.
  • sockets do not support file-like .read() and .write(), so all code you write has to know that it is dealing specifically with a socket. Almost all code doesn't care, and would be better off without this difference. (A great deal of code is probably incorrectly using .send() instead of .sendall() as a result, too.)

  • SSL sockets reverse this; they have .read() and .write(), but not the usual socket set. So code you write has to care whether your socket connection is SSL-wrapped or not.
  • SSL sockets lack any means of closing down the connection. Not only do you not get a .shutdown(), you don't even get a .close(). Apparently you are supposed to shoot them in the head or something.
  • for extra fun, an SSL connection throws an exception when it closes down. Even if it closes in a perfectly orderly manner because the other end told it using the right SSL magic.

I have a Python program that tries to do a simple network cat for SSL connections; these interface issues make it absurdly annoying, and the comments are fully of grumpy rants about it. (The program does work, and I suppose I should put it up on the net sometime.)

Despite all this, I have to say that the socket module makes dealing with the BSD sockets API relatively simple and clear while keeping pretty much all of the features available. Writing socket using programs in Python is significantly easier than doing so in C. (And somewhat easier than doing so in Perl, because Perl forces a somewhat lower level view of the whole mess.)

(Update: I think I've unfairly maligned Perl in my aside; see the comments.)


Comments on this page:

By DanielMartin at 2006-05-20 08:27:43:

(And somewhat easier than doing so in Perl, because Perl forces a somewhat lower level view of the whole mess.)

"Forces" is a bit strong, since perl has included the IO::Socket module as part of the base perl distribution since version 5.004 (May 1997). With that module, you can do stuff like this:

   #!/usr/bin/perl -w
   use IO::Socket;
   use strict;
   my $remote = IO::Socket::INET->new(
		Proto    => "tcp",
		PeerAddr => "localhost",
		PeerPort => "daytime(13)",
	    )
	  or die "cannot connect to daytime port at localhost";
   while ( <$remote> ) { print }

This seems pretty straightforward to me. If that's too verbose you can call the constructor as

   my $remote = IO::Socket::INET->new( "localhost:13" )

True, you can use the low-level socket stuff directly if you want, and a regrettable amount of example code will recommend that instead of IO::Socket, but that's hardly on the same level as the language forcing you to use the low-level interface.

From 129.241.93.32 at 2006-05-20 08:36:37:

Why would you want to write a separate Python program for SSL-aware netcat? "openssl s_client" works just fine...

- Steinar H. Gunderson (sgunderson@bigfoot.com, just in case)

By cks at 2006-05-20 17:06:30:

openssl s_client isn't useful for scripting, because it prints too much goop (even with -quiet, and -quiet turns off handling of input EOF). And even though I could use it for command line usage all of the goop annoys the heck out of me in the majority of the cases when it's not interesting.

In testing I see that openssl also kills the entire connection on input EOF, which is not at all what you want in a netcat-like program; it should shut down the sending end, but keep receiving until network EOF.

By cks at 2006-05-20 17:18:03:

Oops, it looks like I missed reading IO:Socket::INET carefully when I last wrote a Perl network program; in hindsight it provides all of the stuff that I want, and at the same high level that Python provides.

Is IO::Socket a standard part of the Perl distribution? If it is, maybe it's time for the perlfunc manpage to cover it when discussing the low-level socket stuff.

Written on 20 May 2006.
« Some modest suggestions on vendor tradeshow giveaways
Weekly spam summary on May 20th, 2006 »

Page tools: View Source, View Normal, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Sat May 20 03:29:45 2006
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.