thehowev7.1

| blog

[x]
[x]

Posts tagged "computers"

MythTV Script to allow multiple Telnet connections

Sat Jan 12, 2008 11:41:08 PM by Travis

So, my roomate Brock has a MythTV box set up in our apartment, which we use as a free, open-source alternative to Tivo and other commercial DVR products.

One of the nifty things that myth provides is a Telnet interface for controlling the system: just telnet into a certain port, and you can enter in commands to control the system remotely. Works great if you don't have a remote control for the computer that's running myth. Brock and I both have GUI programs we can run on our laptops to provide a nice remote-control-esque interface to the Telnet connection (he uses one he found for Mac, I use one I developed in C# (but that's another blog post)).

It's a great setup, except for one problem: only one user can be connected to myth's telnet interface at a time. So, if Brock is using his remote control program, and I use mine, it automatically disconnects Brock. It's a stupid limitation, in my opinion, but that's the way it is.

Earlier this evening, Brock suggested a way to get around that problem: set up a simple telnet proxy server, which allows multiple clients to connect to it, and forwards all commands over a single connection to the myth telnet interface. Since I was in a mood to code, I decided I'd see if I could write up a simple Ruby program to do just that.

An hour and a half later, I had it working. Well, kinda - it's a little rough, and it doesn't forward the server's replies back to the clients, but it's enough to have multiple remotes simultaneously connected. I've pasted the code at the bottom of this post, as it's only about 90 lines. I'm really rather amazed that it was so easy, largely in part to the excellent gserver library, which may be my new favorite standard library class ever.

Edit 1/17: Updated the code to a cleaner, slightly more concise version.

I love ruby.

#!/usr/bin/ruby require "gserver" require "net/telnet" require "thread" class TelnetProxy < GServer def initialize(*args) super(*args) @@total_num_clients = 0 @cmds = Queue.new end def start(*args) start_myth_connection super(*args) end def serve(io) @@total_num_clients += 1 my_client_id = @@total_num_clients puts("New Client #{my_client_id} detected") # send the initial login msg welcome_msg = "MythFrontend Network Control\nType 'help' for usage information---------------------------------\n# " io.write(welcome_msg) loop do puts "Client #{my_client_id} is still alive" # every 2 seconds check for newly received commands if IO.select([io], nil, nil, 2) # retrieve the data cmd = io.gets puts "Client #{my_client_id} got cmd '#{cmd}'" # if the command was "exit", then disconnect the user, but not the main connection if cmd =~ /exit/ puts "Closing client #{my_client_id} connection..." break end # forward the command to myth @cmds << cmd puts "Client #{my_client_id} placed cmd on queue" # send the response to the user response = "OK\n# " io.write(response) end end end private def start_myth_connection @myth_thread = Thread.new do loop do myth = Net::Telnet::new("Host" => "myth", "Port" => 6545, "Timeout" => 10, "Prompt" => /# /) puts "Connected to myth" cmds_to_run = [] until myth.closed? # get command from the shared buffer (sleeps if none available) cmd = @cmds.pop # send the commands to myth puts "Sending command to myth: #{cmd}" myth.cmd(cmd) puts "Cmd sent" end # until myth.closed? puts "Lost connection to myth" end # loop do end end end proxy = TelnetProxy.new(6546, "myth") proxy.start proxy.join

Misprediction and Evolution vs Revolution

Tue Oct 30, 2007 12:33:03 AM by Travis

On the walk home tonight, I found myself thinking about the difficulty of making predictions, specifically in the technology and business world. The problem is not that the predictors are unintelligent; see Bill Gate's infamous "640K ought to be enough for anybody" quote. Others are well documented at the bad predictions archive.

So, if we can't blame the bad predictions on the predictors, there must be something inherently difficult about making predictions. This idea is, I think, where the difficulty comes in. It turns out, making good predictions isn't really all that hard. See, for example, Moore's Law, Brook's Law, and Hofstadter's Law. All it takes is understanding of past trends, a little insight, and the egotism to name a Law after yourself. Easy, right?

Okay, so if making predictions is really so simple, why aren't we better at it? This is the realization that I had tonight: people are very good at predicting evolutionary changes, often well in advance of when they happen. People are terrible at predicting revolutionary changes, often even when the change is happening around them.

For the sake of this argument, evolutionary changes are defined as conceptually improvements and refinements of existing techniques. For example, cramming more circuits onto a chip, or making fuels that burn cleaner. These kind of changes come from a process of slow and steady improvement, and as such can be easily predicted based on past results.

Revolutionary changes are a little harder to define. They often take the form of a completely different way of doing things, a complete paradigm shift. They might be completely new inventions, or a sudden inspired combination of existing technologies into a whole greater than the sum of its parts. Examples: the computer, the printing press, the cell phone, the internet. These kind of changes are nearly impossible to predict, and are often even incredibly difficult to recognize as they are happening. Predicting revolutionary changes is firmly set in the realm of Science Fiction.

So, what's the moral of the story? Evolutionary changes are easy to predict. Revolutionary changes are not. We must simply remember that there is a difference between the two, and hope to be lucky enough to correctly identify a revolutionary change when it's happening.

Random Randomness

Sun Sep 03, 2006 11:11:55 PM by Travis

I noticed something today. All summer while I was in Seattle I was using my laptop for all my computing needs. Now that I'm back at school I've got my desktop set back up, and I'm starting to use it again. What I've discovered is that owning two computers is kind of like having two families that you keep hidden from each other. You go to open a file, but then realize "oh, it's on my other computer." And the laptop is newer than the desktop, so it's like on of the wives is younger and prettier than the other.

I have to say, the whole situation is just a little awkward.

Post-Thanksgiving Update

Mon Nov 29, 2004 01:30:08 AM by Travis

Gee, it's been awhile. Let's see, I managed to make it through Thanksgiving break without getting any work done. As usual. That, combined with mounds of mouth-wateringly good food, made me a very happy camper. I ended up not taking the ole Xbox home over break - I'm blasting through Legendary on Halo 2 faster than I thought as it is, and I'd like to leave some for Christmas break.

So my DVD/CDRW combo drive on my laptop broke, and the company I bought it from has since gone out of business. One of the prices you pay for buying cheap from a small company, I guess. On the downside, this means I'm going to have to spend between $80 and $150 of my own money to get the damn thing replaced, which is definitely not cool. You really have to pay for the slim design on those internal drives. On the other hand, I now have a fun, broken toy to take apart. I plan on attacking it Tuesday after my Latin exam.

In other news, I've played enough Halo 2 by now to come to the conclusion that it's not as good as Halo 1. However, with a few new maps and some bug fixes over Xbox live, it has the potential to be much better. I'll write up a more detailed review sometime over Christmas break. I won't really have time before then; the semester's winding down. Two full weeks of classes left, then a final week during which I have two days of classes, four exams, two projects, and a paper due. Fun fun. (Of course, on the plus side I'll be home a whole week before some chumps. Ha ha.)

01001010 01110101 01110011 01110100 00100000 01110111 01101000 01100101 01101110 00100000 01110100 01101000 01100101 01111001 00100000 01110100 01101000 01101001 01101110 01101011 00100000 01110100 01101000 01100101 01111001 00100000 01100111 01101111 01110100 00100000 01100001 01101100 01101100 00100000 01110100 01101000 01100101 00100000 01100001 01101110 01110011 01110111 01100101 01110010 01110011 00101100 00100000 00111100 01101001 00111110 01001001 00100000 01100011 01101000 01100001 01101110 01100111 01100101 00100000 01110100 01101000 01100101 00100000 01110001 01110101 01100101 01110011 01110100 01101001 01101111 01101110 01110011 00111100 00101111 01101001 00111110 00101110